BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
ari
Quartz | Level 8 ari
Quartz | Level 8

ID

Time Concentration
1017
100
10.02639.5
10.03130.4
10.0429.2
10.05117.8
10.09230.3
10.17671.5
10.342251
10.508291
11.015360
12.015359
13.014617
14.01502
15.014693
16.016672
17.019529
18.02492
19.017590
110.013490
111.014548
112.013443
113.013449
114.013422
130.012295
158.019268
1120.943214
1211.019185
1242.995125
1272.994137
1305.993156
1334.998135
1366.027160
1393.053127
1424.996131
1456.99139
1484.996120
1515.981115
1544.015114
1578.994133
1608.986120
1638.001116
1658.993122
1695.088136
1726.001132
1726.03237
1726.051183
1726.092151
1726.176155
1726.342181
1727.015118
1728.01472.8
1729.01254.6
1730.02148.1
2015
200
20.02127.1
20.03374.9
20.052142
20.094191
20.18197
20.346242
20.51350
21.015442
22.015555
23.01593
24.013540
25.016425
26.016460
27.02610
29514
210.001466
211.007503
212.014415
213.024458
214.017448
228.03544.7
256.02366
288.033278
2120.026247
2215.973228
2246.013186
2276.978251
2306.206210
2334.98190
2365.073183
2393.094179
2425.052217
2456.056180
2484.043290
2522.051317
2550.059201
2582.078339
2600.007203
2600.045256
2600.068266
2600.108183
2600.191186
2600.358146
2601.18181.2
2602.10665
2603.07331.5
2604.07523.2

Hi All,

 

I need to calculate the area under curve per subject.

I would appreciate any help.

 

Thanks in advance.

 

1 ACCEPTED SOLUTION

Accepted Solutions
PGStats
Opal | Level 21

Yes, I think this would do it:

 

data areas;
startArea = 0;
do until(last.id);
    set have; by id time;
	/* Keep only last observation for any given time value */
    if last.time then do;
		/* Sum a term to trapezoid rule integration */
        area = sum(area, mean(concentration, prevConcentration) * 
            range(time, prevTime));
		/* Look for integration segment limit (multiple of 90) */
        if not missing(prevTime) then 
            if int(time/90) > int(prevTime/90) then do; /* segment limit crossed */
                time90 = 90 * int(time/90);
				/* Interpolate area at segment limit */
                area90 = (prevArea * (time-time90) + area * (time90-prevTime)) / 
                    (time-prevTime) - startArea;
                output;
                startArea = area90;
                end;
        prevConcentration = concentration;
        prevTime = time;
        prevArea = area;
        end;
    end;
keep id time90 area90;
run;

 

Edit : Added comments. 

PG

View solution in original post

19 REPLIES 19
PGStats
Opal | Level 21

How do you wish to handle the multiple values at time = 0 (mean, first, last) ?

PG
ari
Quartz | Level 8 ari
Quartz | Level 8
Hi PG,

Thanks for your response.

I would take the last value at time=0.

PGStats
Opal | Level 21

Try this:

 

data want;
do until(last.id);
    set have; by id time;
    if last.time then 
        area = sum(area, mean(concentration, prevConcentration) * 
            range(time, prevTime));
    prevConcentration = concentration;
    prevTime = time;
    end;
keep id area;
run;

 

Edit: Replaced sum statement with sum function so that the sum doesn't carry from one ID to the next. 

PG
FreelanceReinh
Jade | Level 19

Nice implementation. There should be no duplicate time values other than the first for an ID, though.

ari
Quartz | Level 8 ari
Quartz | Level 8

Hi PG,

 

Thanks for the code.

 

Is there a way to calculate the AUC in intervals (partial AUC) of 90 days?

 

Thanks

PGStats
Opal | Level 21

Yes, I think this would do it:

 

data areas;
startArea = 0;
do until(last.id);
    set have; by id time;
	/* Keep only last observation for any given time value */
    if last.time then do;
		/* Sum a term to trapezoid rule integration */
        area = sum(area, mean(concentration, prevConcentration) * 
            range(time, prevTime));
		/* Look for integration segment limit (multiple of 90) */
        if not missing(prevTime) then 
            if int(time/90) > int(prevTime/90) then do; /* segment limit crossed */
                time90 = 90 * int(time/90);
				/* Interpolate area at segment limit */
                area90 = (prevArea * (time-time90) + area * (time90-prevTime)) / 
                    (time-prevTime) - startArea;
                output;
                startArea = area90;
                end;
        prevConcentration = concentration;
        prevTime = time;
        prevArea = area;
        end;
    end;
keep id time90 area90;
run;

 

Edit : Added comments. 

PG
ari
Quartz | Level 8 ari
Quartz | Level 8
Thanks PG.

Please explain briefly how the calculation works.
PGStats
Opal | Level 21

I added some comments to the code.

PG
Jack2012
Obsidian | Level 7

To be honest, I have not fully understand the mechanism of such algorithm, but it is easier to use and more illustrative compare with PROC IML and post by Rick.

 

Jack.

Jack2012
Obsidian | Level 7
data have;
infile cards expandtabs truncover;
input ID rho Time 	Concentration;
cards;
1	1 0	17
1	1 0	0
1	1 0.026	39.5
1	1 0.031	30.4
1	1 0.04	29.2
1	1 0.051	17.8
1	1 0.092	30.3
1	1 0.176	71.5
1	1 0.342	251
1	1 0.508	291
1	1 1.015	360
1	1 2.015	359
1	1 3.014	617
1	1 4.01	502
1	1 5.014	693
1	1 6.016	672
1	1 7.019	529
1	1 8.02	492
1	1 9.017	590
1	1 10.013	490
1	1 11.014	548
1	1 12.013	443
1	1 13.013	449
1	2 14.013	422
1	2 30.012	295
1	2 58.019	268
1	2 120.943	214
1	2 211.019	185
1	2 242.995	125
1	2 272.994	137
1	2 305.993	156
1	2 334.998	135
1	2 366.027	160
1	2 393.053	127
1	2 424.996	131
1	2 456.99	139
1	2 484.996	120
1	2 515.981	115
1	2 544.015	114
1	2 578.994	133
1	2 608.986	120
1	2 638.001	116
1	2 658.993	122
1	2 695.088	136
1	2 726.001	132
1	2 726.03	237
1	2 726.051	183
1	2 726.092	151
1	2 726.176	155
1	2 726.342	181
1	2 727.015	118
1	2 728.014	72.8
1	2 729.012	54.6
1	2 730.021	48.1
2	1 0	15
2	1 0	0
2	1 0.021	27.1
2	1 0.033	74.9
2	1 0.052	142
2	1 0.094	191
2	1 0.18	197
2	1 0.346	242
2	1 0.51	350
2	1 1.015	442
2	1 2.015	555
2	1 3.01	593
2	1 4.013	540
2	1 5.016	425
2	1 6.016	460
2	1 7.02	610
2	1 9	514
2	1 10.001	466
2	1 11.007	503
2	1 12.014	415
2	1 13.024	458
2	1 14.017	448
2	1 28.035	44.7
2	1 56.02	366
2	1 88.033	278
2	2 120.026	247
2	2 215.973	228
2	2 246.013	186
2	2 276.978	251
2	2 306.206	210
2	2 334.98	190
2	2 365.073	183
2	2 393.094	179
2	2 425.052	217
2	2 456.056	180
2	2 484.043	290
2	2 522.051	317
2	2 550.059	201
2	2 582.078	339
2	2 600.007	203
2	2 600.045	256
2	2 600.068	266
2	2 600.108	183
2	2 600.191	186
2	2 600.358	146
2	2 601.181	81.2
2	2 602.106	65
2	2 603.073	31.5
2	2 604.075	23.2
;
run;

How should I modify you code to calculate the area by id and rho? Many thanks.

 

 

Jack

Ksharp
Super User

There is trapezoidal rule  which can approximate get the area under curve. Check Rick's blog:

http://blogs.sas.com/content/iml/2011/06/01/the-trapezoidal-rule-of-integration.html

 

Jack2012
Obsidian | Level 7

Yes, you  are right, I followed this post to calculate the area.

ari
Quartz | Level 8 ari
Quartz | Level 8

Thanks Xia. will check it

Jack2012
Obsidian | Level 7

Dear Keshan,

 

I have referred to this post by Rick. The question I am facing is how to make use of this by SUBJECT. I mean by use of the PROC IML as used by Rick.

 

I think there is no BY statement available in PROC IML.

 

Appreicated for your quick response.

 

Jack.

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

What is ANOVA?

ANOVA, or Analysis Of Variance, is used to compare the averages or means of two or more populations to better understand how they differ. Watch this tutorial for more.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 19 replies
  • 10461 views
  • 4 likes
  • 5 in conversation