Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Plotting of repeated measures over time

    Hello! Stata novice here.

    I have the following data which is looking at peak systolic velocities (PSVs) of blood flow through an artery measured using Doppler ultrasound, and the cohort are divided by whether the artery is calcified or not:
    Calcification Time to Doppler 1 PSV 1 Time to Doppler 2 PSV 2 Time to Doppler 3 PSV 3 Time to Doppler 4 PSV 4 Time to Doppler 5 PSV 5 Time to Doppler 6 PSV 6 Time to Doppler 7 PSV 7 Time to Doppler 8 PSV 8
    1 41 206 419 300
    1 84 400
    1 19 60 1251 150 1540 111
    0 55 375 118 500 314 372
    1 202 250
    1 92 260 309 241 505 300
    0 452 72
    0 484 240
    0 33 232 131 230 343 400 467 377 3929 400 1013 324 1762 300 2112 244
    0 762 221 895 163
    1 56 53
    1 97 112
    0 168 150 258 276
    0 134 128
    0 76 100 454 400 573 450
    1 167 213 524 400 888 400
    0 362 420
    1 89 500
    0 1890 170 2177 136 2380 380
    0 392 200
    1 680 290 1079 217
    0 680 0 1079 175
    0 40 100
    0 117 233 322 257 406 300
    0 1196 350
    0 105 203
    1 104 280 237 299 335 177 699 186 1583 143
    1 98 238 231 155 329 160 693 170 1577 124
    0 230 350 398 600
    1 343 280 707 210 1078 150 1820 149 2170 184
    1 343 227 707 227 1078 200 1820 175 2170 139
    0 916 0
    1 70 150
    0 74 194 466 0
    0 241 178 517 500
    1 147 127
    0 215
    1 490 130
    0 19 200 418 220 796 180
    1 94 250 290 350
    0 141 228 344 137
    These patients undergo follow-up Dopplers at different time points, and different patients have had a varying number of follow ups over time. I'm hoping to create line graphs (or another appropriate plot) which the progresion of these velocities over time of calcified vs non-calcified arteries; for instance where time (days) is on the x axis, velocity is on the y axis, the calcified values are plotted with an X and solid lines, non calcified with O and dotted lines, and each artery is plotted as an individual line. I've searched everywhere online with no luck, so would appreciate assistance!
    Last edited by Ashar Asif; 10 Apr 2024, 05:38.

  • #2
    Hello Ashar Asif and welcome to this forum. You will make it much easier for other members to help you if you use the -dataex- command to provide a sample of your data. See item 12 in the FAQ: https://www.statalist.org/forums/help

    Thanks,
    Bruce
    --
    Bruce Weaver
    Email: [email protected]
    Version: Stata/MP 18.5 (Windows)

    Comment


    • #3
      Originally posted by Bruce Weaver View Post
      You will make it much easier for other members to help you if you use the -dataex- command to provide a sample of your data.
      Well, I hope that it's all of Ashar's data and not just a sample, but here (if I haven't erred):
      Code:
      input byte(pid vis cal) int(tim vel)
       1 1 1   41 206
       1 2 1  419 300
       2 1 1   84 400
       3 1 1   19  60
       3 2 1 1251 150
       3 3 1 1540 111
       4 1 0   55 375
       4 2 0  118 500
       4 3 0  314 372
       5 1 1  202 250
       6 1 1   92 260
       6 2 1  309 241
       6 3 1  505 300
       7 1 0  452  72
       8 1 0  484 240
       9 1 0   33 232
       9 2 0  131 230
       9 3 0  343 400
       9 4 0  467 377
       9 5 0 3929 400
       9 6 0 1013 324
       9 7 0 1762 300
       9 8 0 2112 244
      10 1 0  762 221
      10 2 0  895 163
      11 1 1   56  53
      12 1 1   97 112
      13 1 0  168 150
      13 2 0  258 276
      14 1 0  134 128
      15 1 1  167 213
      15 2 1  524 400
      15 3 1  888 400
      16 1 0  362 420
      17 1 1   89 500
      18 1 0 1890 170
      18 2 0 2177 136
      18 3 0 2380 380
      19 1 0  392 200
      20 1 1  680 290
      20 2 1 1079 217
      21 1 0  680   0
      21 2 0 1079 175
      22 1 0   40 100
      23 1 0  117 233
      23 2 0  322 257
      23 3 0  406 300
      24 1 0 1196 350
      25 1 0  105 203
      26 1 1  104 280
      26 2 1  237 299
      26 3 1  335 177
      26 4 1  699 186
      26 5 1 1583 143
      27 1 1   98 238
      27 2 1  231 155
      27 3 1  329 160
      27 4 1  693 170
      27 5 1 1577 124
      28 1 0  230 350
      28 2 0  398 600
      29 1 1  343 280
      29 2 1  707 210
      29 3 1 1078 150
      29 4 1 1820 149
      29 5 1 2170 184
      30 1 1  343 227
      30 2 1  707 227
      30 3 1 1078 200
      30 4 1 1820 175
      30 5 1 2170 139
      31 1 0  916   0
      32 1 1   70 150
      33 1 0   74 194
      33 2 0  466   0
      34 1 0  241 178
      34 2 0  517 500
      35 1 1  147 127
      37 1 1  490 130
      38 1 0   19 200
      38 2 0  418 220
      38 3 0  796 180
      39 1 1   94 250
      39 2 1  290 350
      40 1 0  141 228
      40 2 0  344 137
      end
      label variable pid "Patient ID"
      label variable vis "Visit Nr"
      label variable cal "Calcification"
      label define NY 0 N 1 Y
      label values cal NY
      label variable tim "Time to doppler sonographic evaluation (d)"
      label variable vel "Peak systolic velocity (cm/s)"
      Ashar, thank you for posting your question: it prompted me to look at mkspline again after a long hiatus, and to discover that it's now upgraded to makespline. Quite an enhancement.

      Comment


      • #4
        Thanks for the heads-up about -makespline-, Joseph Coveney. Typing help mkspline still opens a help window, but with this message at the top:

        mkspline has been renamed to makespline. mkspline continues to work but, as of Stata 18, is no longer an official part of
        Stata. This is the original help file, which we will no longer update, so some links may no longer work.
        --
        Bruce Weaver
        Email: [email protected]
        Version: Stata/MP 18.5 (Windows)

        Comment


        • #5
          Bruce Weaver Joseph Coveney Hi, thanks for your reply and thanks for pointing out the formatting. I will keep note of that and use it from now on. Here is the data reformatted:


          Code:
          * Example generated by -dataex-. For more info, type help dataex
          clear
          input byte(No Calcification) int(TimetoDoppler1 PSV1 TimetoDoppler2 PSV2 TimetoDoppler3 PSV3 TimetoDoppler4 PSV4 TimetoDoppler5 PSV5 TimetoDoppler6 PSV6 TimetoDoppler7 PSV7 TimetoDoppler8 PSV8)
           1 1    .   .    .   .    .   .    .   .    .   .    .   .    .   .    .   .
           2 1    .   .    .   .    .   .    .   .    .   .    .   .    .   .    .   .
           3 1    .   .    .   .    .   .    .   .    .   .    .   .    .   .    .   .
           4 1   41 206  419 300    .   .    .   .    .   .    .   .    .   .    .   .
           6 1   84 400    .   .    .   .    .   .    .   .    .   .    .   .    .   .
           7 1   19  60 1251 150 1540 111    .   .    .   .    .   .    .   .    .   .
           8 0   55 375  118 500  314 372    .   .    .   .    .   .    .   .    .   .
           9 0    .   .    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          10 1    .   .    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          11 1    .   .    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          12 0    .   .    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          13 1    .   .    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          14 1  202 250    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          15 1   92 260  309 241  505 300    .   .    .   .    .   .    .   .    .   .
          16 0  452  72    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          17 0  484 240    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          18 1    .   .    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          19 1    .   .    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          20 1    .   .    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          21 1    .   .    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          22 1    .   .    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          23 0   33 232  131 230  343 400  467 377 3929 400 1013 324 1762 300 2112 244
          24 1    .   .    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          25 1    .   .    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          26 0    .   .    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          27 0    .   .    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          28 0  762 221  895 163    .   .    .   .    .   .    .   .    .   .    .   .
          29 0    .   .    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          30 1   56  53    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          31 1   97 112    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          32 1    .   .    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          33 0  168 150  258 276    .   .    .   .    .   .    .   .    .   .    .   .
          34 0  134 128    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          35 0    .   .    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          36 0   76 100  454 400  573 450    .   .    .   .    .   .    .   .    .   .
          37 0    .   .    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          38 0    .   .    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          39 1  167 213  524 400  888 400    .   .    .   .    .   .    .   .    .   .
          40 0  362 420    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          41 0    .   .    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          42 1   89 500    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          43 0    .   .    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          44 0    .   .    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          45 0 1890 170 2177 136 2380 380    .   .    .   .    .   .    .   .    .   .
          46 1    .   .    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          47 0  392 200    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          48 1    .   .    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          49 1    .   .    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          50 1    .   .    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          51 1  680 290 1079 217    .   .    .   .    .   .    .   .    .   .    .   .
          52 0  680   0 1079 175    .   .    .   .    .   .    .   .    .   .    .   .
          53 0   40 100    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          54 0    .   .    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          55 0  117 233  322 257  406 300    .   .    .   .    .   .    .   .    .   .
          56 0 1196 350    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          57 0    .   .    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          58 0  105 203    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          59 1  104 280  237 299  335 177  699 186 1583 143    .   .    .   .    .   .
          60 1   98 238  231 155  329 160  693 170 1577 124    .   .    .   .    .   .
          61 0    .   .    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          62 0  230 350  398 600    .   .    .   .    .   .    .   .    .   .    .   .
          63 1  343 280  707 210 1078 150 1820 149 2170 184    .   .    .   .    .   .
          64 1  343 227  707 227 1078 200 1820 175 2170 139    .   .    .   .    .   .
          65 1    .   .    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          66 0  916   0    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          67 1   70 150    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          68 1    .   .    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          69 1    .   .    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          70 0   74 194  466   0    .   .    .   .    .   .    .   .    .   .    .   .
          72 1    .   .    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          73 1    .   .    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          74 0  241 178  517 500    .   .    .   .    .   .    .   .    .   .    .   .
          75 1    .   .    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          76 1  147 127    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          77 0  215   .    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          78 1  490 130    .   .    .   .    .   .    .   .    .   .    .   .    .   .
          79 0   19 200  418 220  796 180    .   .    .   .    .   .    .   .    .   .
          94 1   94 250  290 350    .   .    .   .    .   .    .   .    .   .    .   .
          95 0  141 228  344 137    .   .    .   .    .   .    .   .    .   .    .   .
          end
          Last edited by Ashar Asif; 11 Apr 2024, 06:34.

          Comment


          • #6
            Originally posted by Ashar Asif View Post
            Here is the data reformatted:
            Seems to have a few more observations than in the first post.

            You can make overlaid individual line plots, but the graph might be a little busy. Because you have repeated measurements, how about fitting a mixed model and plotting the predictions? Maybe something along the following lines.
            Code:
            version 18.0
            
            clear *
            
            quietly input byte(No Calcification) int(TimetoDoppler1 PSV1 TimetoDoppler2 ///
                PSV2 TimetoDoppler3 PSV3 TimetoDoppler4 PSV4 TimetoDoppler5 PSV5 ///
                TimetoDoppler6 PSV6 TimetoDoppler7 PSV7 TimetoDoppler8 PSV8)
            <redacted for brevity>
            end
            
            rename No pid
            rename PSV? vel?
            rename TimetoDoppler? tim?
            rename Calcification cal
            
            quietly reshape long tim vel, i(pid) j(vis)
            quietly drop if mi(vel)
            
            label variable pid "Patient ID"
            label variable vis "Visit Nr"
            label variable cal "Calcification"
            label define NY 0 N 1 Y
            label values cal NY
            label variable tim "Time to Doppler Sonographic Evaluation (d)"
            label variable vel "Peak systolic velocity (cm/s)"
            
            set type double
            
            /* Nonmonotonic relationship between blood velocity and degree of lumenal
               narrowing (velocity increases with stenosis until occlusion, when it goes
               to zero) */
            summarize vel, meanonly
            generate int vma = cond(!vel, r(max), vel)
            
            // Impose common maximum follow-up interval (avoid differential sparseness)
            version 16.1: table cal, contents(min tim median tim max tim)
            summarize tim if !cal, meanonly
            local max `r(max)'
            summarize tim if cal, meanonly
            local max = min(`max', r(max))
            
            // LOWESS (for reference)
            quietly separate vma, by(cal) veryshortlabel
            lowess vma0 tim, generate(lma0) nograph
            lowess vma1 tim, generate(lma1) nograph
            graph twoway ///
                line lma0 tim if tim <= `max', sort lcolor(red) || ///
                    scatter vma0 tim if tim <= `max', mcolor(red) msize(tiny) || ///
                line lma1 tim if tim <= `max', sort lcolor(blue) || ///
                    scatter vma1 tim if tim <= `max', mcolor(blue) msize(tiny) ///
                ytitle(Peak Systolic Velocity (cm/s)) ylabel( , angle(horizontal) nogrid) ///
                scheme(s2color) legend(off)
            quietly graph export LOWESS.png
            
            // Four-knot restricted cubic spline (Harrell-recommended knot locations)
            mkspline sp = tim if tim <= `max', cubic nknots(4)
            mixed vma i.cal##c.(sp?) if tim <= `max'|| pid: , reml dfmethod(kroger) ///
                nolrtest nolog
            testparm cal#c.sp1 cal#c.sp2 cal#c.sp3, small
            contrast cal, small
            testparm sp1 sp2 sp3 , small
            
            quietly predict double xb, xb
            quietly separate xb, by(cal) veryshortlabel
            graph twoway ///
                line xb0 tim if tim <= `max', sort lcolor(red) || ///
                    scatter vma0 tim if tim <= `max', mcolor(red) msize(tiny) || ///
                line xb1 tim if tim <= `max', sort lcolor(blue) || ///
                    scatter vma1 tim if tim <= `max', mcolor(blue) msize(tiny) ///
                ytitle(Peak Systolic Velocity (cm/s)) ylabel( , angle(horizontal) nogrid) ///
                scheme(s2color) legend(off)
            quietly graph export Spline.png
            
            exit
            Attached Files
            Last edited by Joseph Coveney; 11 Apr 2024, 07:16.

            Comment


            • #7
              Joseph Coveney Thank you so much! Agreed, when I think about it, individual lines for each patient would make it hard to follow, I think this spline approach is perfect- thank you!

              Comment

              Working...
              X