Hi SMEs,
I am seeking your help to resolve the issues I am facing with the derived visit.
I have attached my_output.xlsx and i_need.xlsx.
The file my_output.xlsx was generated using the SAS code below; however, I need the output to match i_need.xlsx.
Logic implemented:
Week 1 to Week 12 (weekly): when 1 < ADY ≤ 84
Week 1 is derived by taking the worst AVAL from Day 1 to Day 7
Continue similarly up to Week 12 (Day 78 to Day 84)
Week 15 to End of Treatment day. (every 3 weeks): when 85 ≤ ADY ≤ EOTDY
Week 15 is derived by taking the worst AVAL from Day 85 to Day 105. Repeat this process every 3 weeks until the end of treatment day. (EOTDY).
The above logic is used to derive the worst value per USUBJID / PARAMCD / AVISITN.
For these derived records, DTYPE = WOCF is assigned and appended to the original dataset.
I have created a new variable, NEW_AVISITN, to implement this logic without affecting the existing AVISITN. However, I am not getting the expected values.
| 101 | ABCD02W | 2025-03-14T16:56:00 | 9 | Week 9 | 57 | 354 | WOCF | Slightly severe | 2 |
| 101 | ABCD02W | 2025-03-16T18:02:00 | 9 | Week 9 | 59 | 354 | WOCF | Severe | 3 |
| 101 | ABCD02W | 2025-04-04T17:45:00 | 12 | Week 12 | 78 | 354 | WOCF | Not severe | 1 |
| 101 | ABCD02W | 2025-04-05T18:46:00 | 12 | Week 12 | 79 | 354 | WOCF | Slightly severe | 2 |
data test1;
set test;
by usubjid avisitn;
retain max_ady;
/* Calculate maximum ADY for each subject on first observation */
if first.usubjid then do;
max_ady = .;
end;
/* Track the maximum ADY value */
if not missing(ady) then do;
max_ady = max(max_ady, ady);
end;
/* Derive visit number and visit name for every observation */
if not missing(ady) then do;
eotdy_value = coalesce(eotdy, max_ady);
if 1 < ady <= 84 then do;
/* Week 1 to Week 12 (every week) when 1 < ADY <= 84 */
/* Day 1-7 = Week 1, Day 8-14 = Week 2, ..., Day 78-84 = Week 12 */
new_avisitn = ceil((ady - 1) / 7);
new_avisit = catx(" ", "Week", put(new_avisitn, best.));
end;
else if not missing(eotdy_value) and 85 <= ady <= eotdy_value then do;
/* After Week 12 every 3 weeks when 85 <= ADY <= EOTDY */
/* Day 85-105 = Week 15, Day 106-126 = Week 18, Day 127-147 = Week 21, etc. */
/* Formula: Week = 15 + floor((ady - 85) / 21) * 3 */
new_avisitn = 15 + floor((ady - 85) / 21) * 3;
new_avisit = catx(" ", "Week", put(new_avisitn, best.));
end;
else do;
call missing(new_avisitn, new_avisit);
end;
end;
else do;
call missing(new_avisitn, new_avisit);
end;
output;
run;
Could you please let me which mistake I am doing here or please provide me a simple solution for this problem.
Many users here don't want to download Excel files because of virus potential, others have such things blocked by security software. Also if you give us Excel we have to create a SAS data set and due to the non-existent constraints on Excel data cells the result we end up with may not have variables of the same type (numeric or character) and even values.
You also do not provide any STARTING data at all. As a minimum we would need a working data step that creates a TEST data set that will yield a similar behavior to your problem. The data step code should be pasted into a text or code box, opened on the forum by clicking on either the </> or "running man" icon above the main message window. These boxes will prevent the forum software from reformatting code such as by removing indentation if any was used and has been known to introduce artifacts into code so that it will not run as pasted.
Another advantage to the data step is that we can see the names and properties of variables without even running code. Sometimes that is sufficient to answer some questions.
Something else that would be helpful would be to describe what you want help with. Is it only the assignment of the visit number as implied by your subject is there something involving AVAL because you mention "worst Aval" but do not define that anywhere in the problem. And if that is in the example output you show it isn't labeled so we can't tell.
At which step is your i_need supposed to generated? Since your code doesn't mention that name for a data set the step(s) in question are a bit obtuse.
Also, the "logic" throws out a lot of apparent time intervals but not a clear explanation of what the intervals are used for.
It may not hurt to define what "week" means to you as SAS has some function that are more direct interval calculations. Though I suspect that anything using a changing length and thinking of it as "week" is problematic along those lines.
Without starting data I can see a couple of places that could result in unexpected results.
The most obvious would be having more than one missing ADY value sequentially or identical values of ADY, presumably across whatever PARAMCD is. Which could be occurring on the same date but at different times of day.
Another is where you take the full TEST1 data set and then append records using SET statement. I would almost think that a MERGE on subjid and avistn (or other identifying variables) would make more sense if the purpose is just to add one number.
There are also places that you assign missing to the new_avist and new_avistn variables. Missing is smaller than all other values so the order of processing in the SQL portion of that macro may not be as expected.
You posted two outputs without any inputs. How can we know what you started with? How can we test code without any inputs?
What exactly are you having trouble with?
Is it the grouping of the data into the time periods you described? Are your 3 week groupings at the end disjoint or overlapping? That is do you want weeks 16 to 18 after the grouping of weeks 13 to 15? Or instead do you want a three week window from 14 to 16 and then 15 to 17, etc If the former then what VISITN*VISIT combination do you want store in the dataset for those three week summary stats? Is it Week 13? Or Week 15? Or something else?
Is it the calculation of the summary stat for the grouped values that is causing you trouble?
Is it the addition of extra observations to store those derived summary stats?
Note that spreadsheets are great for doing spreadsheet things, but they are terrible for sharing SAS data. And do you really need to share almost 4,000 observations of data covering 21 weeks to demonstrate the issue you are having?
Thank you so much for your quick response. I will keep in mind that no excel sheets will be attached in the future for any posts.
I really appreciate your help.
I need to derive the worst AVAL per USUBJID / PARAMCD / AVISITN. To get the worst AVAL value. For these derived records, DTYPE = WOCF is assigned, new PARMACD wit suffix of "W" to be assigned and appended to the original dataset. To derive worst record I need to consider the below logic.
Week 1 to Week 12 (weekly): when 1 < ADY ≤ 84
Derive by taking the worst AVAL from Day 1 to Day 7
Continue similarly up to Week 12 (Day 78 to Day 84)
Week 15 to End of Treatment (every 3 weeks): when 85 ≤ ADY ≤ EOTDY
Derive by taking the worst AVAL from Day 85 to Day 105
Repeat this process every 3 weeks until the end of treatment.
Here is the source data.
| USUBJID | PARAMCD | ADTM | AVISITN | AVISIT | ADY | EOTDY | DTYPE | AVALC | AVAL |
| 101 | ABCD0102 | 2025-01-20T12:54:00 | 1 | Week 1 | 4 | 354 | Slightly severe | 2 | |
| 101 | ABCD0102 | 2025-01-21T07:52:00 | 1 | Week 1 | 5 | 354 | Slightly severe | 2 | |
| 101 | ABCD0102 | 2025-01-22T07:16:00 | 1 | Week 1 | 6 | 354 | |||
| 101 | ABCD0102 | 2025-01-23T12:09:00 | 1 | Week 1 | 7 | 354 | |||
| 101 | ABCD0102 | 2025-01-24T17:15:00 | 2 | Week 2 | 8 | 354 | |||
| 101 | ABCD0102 | 2025-01-26T13:10:00 | 2 | Week 2 | 10 | 354 | Severe | 3 | |
| 101 | ABCD0102 | 2025-01-28T11:09:00 | 2 | Week 2 | 12 | 354 | Severe | 3 | |
| 101 | ABCD0102 | 2025-01-30T14:04:00 | 2 | Week 2 | 14 | 354 | Slightly severe | 2 | |
| 101 | ABCD0102 | 2025-02-01T09:23:00 | 3 | Week 3 | 16 | 354 | Slightly severe | 2 | |
| 101 | ABCD0102 | 2025-02-02T19:56:00 | 3 | Week 3 | 17 | 354 | Slightly severe | 2 | |
| 101 | ABCD0102 | 2025-02-03T14:48:00 | 3 | Week 3 | 18 | 354 | Slightly severe | 2 | |
| 101 | ABCD0102 | 2025-02-04T13:22:00 | 3 | Week 3 | 19 | 354 | Slightly severe | 2 | |
| 101 | ABCD0102 | 2025-02-06T18:44:00 | 3 | Week 3 | 21 | 354 | Slightly severe | 2 | |
| 101 | ABCD0102 | 2025-02-08T18:09:00 | 4 | Week 4 | 23 | 354 | Slightly severe | 2 | |
| 101 | ABCD0102 | 2025-02-09T17:24:00 | 4 | Week 4 | 24 | 354 | Not severe | 1 | |
| 101 | ABCD0102 | 2025-02-10T16:40:00 | 4 | Week 4 | 25 | 354 | Not severe | 1 | |
| 101 | ABCD0102 | 2025-02-11T19:27:00 | 4 | Week 4 | 26 | 354 | Not severe | 1 | |
| 101 | ABCD0102 | 2025-02-12T15:52:00 | 4 | Week 4 | 27 | 354 | |||
| 101 | ABCD0102 | 2025-02-13T17:30:00 | 4 | Week 4 | 28 | 354 | |||
| 101 | ABCD0102 | 2025-02-14T16:52:00 | 5 | Week 5 | 29 | 354 | |||
| 101 | ABCD0102 | 2025-02-15T12:33:00 | 5 | Week 5 | 30 | 354 | |||
| 101 | ABCD0102 | 2025-02-16T12:48:00 | 5 | Week 5 | 31 | 354 | |||
| 101 | ABCD0102 | 2025-02-17T14:52:00 | 5 | Week 5 | 32 | 354 | |||
| 101 | ABCD0102 | 2025-02-18T16:06:00 | 5 | Week 5 | 33 | 354 | |||
| 101 | ABCD0102 | 2025-02-19T13:28:00 | 5 | Week 5 | 34 | 354 | |||
| 101 | ABCD0102 | 2025-02-20T14:57:00 | 5 | Week 5 | 35 | 354 | |||
| 101 | ABCD0102 | 2025-02-21T20:02:00 | 6 | Week 6 | 36 | 354 | |||
| 101 | ABCD0102 | 2025-02-22T10:01:00 | 6 | Week 6 | 37 | 354 | |||
| 101 | ABCD0102 | 2025-02-24T17:57:00 | 6 | Week 6 | 39 | 354 | |||
| 101 | ABCD0102 | 2025-02-25T17:27:00 | 6 | Week 6 | 40 | 354 | |||
| 101 | ABCD0102 | 2025-02-26T22:05:00 | 6 | Week 6 | 41 | 354 | |||
| 101 | ABCD0102 | 2025-02-27T18:11:00 | 6 | Week 6 | 42 | 354 | |||
| 101 | ABCD0102 | 2025-02-28T12:29:00 | 7 | Week 7 | 43 | 354 | |||
| 101 | ABCD0102 | 2025-03-01T12:15:00 | 7 | Week 7 | 44 | 354 | |||
| 101 | ABCD0102 | 2025-03-02T10:07:00 | 7 | Week 7 | 45 | 354 | |||
| 101 | ABCD0102 | 2025-03-03T17:29:00 | 7 | Week 7 | 46 | 354 | |||
| 101 | ABCD0102 | 2025-03-04T16:35:00 | 7 | Week 7 | 47 | 354 | |||
| 101 | ABCD0102 | 2025-03-05T15:40:00 | 7 | Week 7 | 48 | 354 | |||
| 101 | ABCD0102 | 2025-03-06T18:23:00 | 7 | Week 7 | 49 | 354 | |||
| 101 | ABCD0102 | 2025-03-07T09:35:00 | 8 | Week 8 | 50 | 354 | |||
| 101 | ABCD0102 | 2025-03-08T14:16:00 | 8 | Week 8 | 51 | 354 | |||
| 101 | ABCD0102 | 2025-03-09T15:13:00 | 8 | Week 8 | 52 | 354 | |||
| 101 | ABCD0102 | 2025-03-10T18:24:00 | 8 | Week 8 | 53 | 354 | |||
| 101 | ABCD0102 | 2025-03-11T11:34:00 | 8 | Week 8 | 54 | 354 | Not severe | 1 | |
| 101 | ABCD0102 | 2025-03-12T12:41:00 | 8 | Week 8 | 55 | 354 | Slightly severe | 2 | |
| 101 | ABCD0102 | 2025-03-13T16:57:00 | 8 | Week 8 | 56 | 354 | Slightly severe | 2 | |
| 101 | ABCD0102 | 2025-03-14T16:56:00 | 9 | Week 9 | 57 | 354 | Slightly severe | 2 | |
| 101 | ABCD0102 | 2025-03-15T17:32:00 | 9 | Week 9 | 58 | 354 | Slightly severe | 2 | |
| 101 | ABCD0102 | 2025-03-16T18:02:00 | 9 | Week 9 | 59 | 354 | Severe | 3 | |
| 101 | ABCD0102 | 2025-03-17T18:32:00 | 9 | Week 9 | 60 | 354 | Slightly severe | 2 | |
| 101 | ABCD0102 | 2025-03-18T18:21:00 | 9 | Week 9 | 61 | 354 | Slightly severe | 2 | |
| 101 | ABCD0102 | 2025-03-19T21:29:00 | 9 | Week 9 | 62 | 354 | Slightly severe | 2 | |
| 101 | ABCD0102 | 2025-03-21T16:19:00 | 10 | Week 10 | 64 | 354 | |||
| 101 | ABCD0102 | 2025-03-22T17:55:00 | 10 | Week 10 | 65 | 354 | |||
| 101 | ABCD0102 | 2025-03-23T16:05:00 | 10 | Week 10 | 66 | 354 | |||
| 101 | ABCD0102 | 2025-03-24T21:32:00 | 10 | Week 10 | 67 | 354 | |||
| 101 | ABCD0102 | 2025-03-25T11:38:00 | 10 | Week 10 | 68 | 354 | |||
| 101 | ABCD0102 | 2025-03-26T17:03:00 | 10 | Week 10 | 69 | 354 | |||
| 101 | ABCD0102 | 2025-03-27T11:55:00 | 10 | Week 10 | 70 | 354 | |||
| 101 | ABCD0102 | 2025-03-28T09:27:00 | 11 | Week 11 | 71 | 354 | |||
| 101 | ABCD0102 | 2025-03-29T19:18:00 | 11 | Week 11 | 72 | 354 | |||
| 101 | ABCD0102 | 2025-03-31T17:05:00 | 11 | Week 11 | 74 | 354 | |||
| 101 | ABCD0102 | 2025-04-01T18:25:00 | 11 | Week 11 | 75 | 354 | |||
| 101 | ABCD0102 | 2025-04-02T16:02:00 | 11 | Week 11 | 76 | 354 | |||
| 101 | ABCD0102 | 2025-04-03T21:57:00 | 11 | Week 11 | 77 | 354 | |||
| 101 | ABCD0102 | 2025-04-04T17:45:00 | 12 | Week 12 | 78 | 354 | Not severe | 1 | |
| 101 | ABCD0102 | 2025-04-05T18:46:00 | 12 | Week 12 | 79 | 354 | Slightly severe | 2 | |
| 101 | ABCD0102 | 2025-04-06T18:10:00 | 12 | Week 12 | 80 | 354 | Not severe | 1 | |
| 101 | ABCD0102 | 2025-04-08T12:00:00 | 12 | Week 12 | 82 | 354 | Slightly severe | 2 | |
| 101 | ABCD0102 | 2025-04-09T13:22:00 | 12 | Week 12 | 83 | 354 | Not severe | 1 | |
| 101 | ABCD0102 | 2025-04-10T17:56:00 | 12 | Week 12 | 84 | 354 | Slightly severe | 2 | |
| 101 | ABCD0102 | 2025-04-11T19:29:00 | 13 | Week 13 | 85 | 354 | Not severe | 1 | |
| 101 | ABCD0102 | 2025-04-12T15:53:00 | 13 | Week 13 | 86 | 354 | Not severe | 1 | |
| 101 | ABCD0102 | 2025-04-13T20:18:00 | 13 | Week 13 | 87 | 354 | Not severe | 1 | |
| 101 | ABCD0102 | 2025-04-14T18:54:00 | 13 | Week 13 | 88 | 354 | |||
| 101 | ABCD0102 | 2025-04-15T19:18:00 | 13 | Week 13 | 89 | 354 | |||
| 101 | ABCD0102 | 2025-04-16T18:08:00 | 13 | Week 13 | 90 | 354 | |||
| 101 | ABCD0102 | 2025-04-17T10:32:00 | 13 | Week 13 | 91 | 354 | |||
| 101 | ABCD0102 | 2025-04-18T16:57:00 | 14 | Week 14 | 92 | 354 | |||
| 101 | ABCD0102 | 2025-04-19T13:51:00 | 14 | Week 14 | 93 | 354 | |||
| 101 | ABCD0102 | 2025-04-20T16:46:00 | 14 | Week 14 | 94 | 354 | |||
| 101 | ABCD0102 | 2025-04-21T16:08:00 | 14 | Week 14 | 95 | 354 | Not severe | 1 | |
| 101 | ABCD0102 | 2025-04-22T17:21:00 | 14 | Week 14 | 96 | 354 | Slightly severe | 2 | |
| 101 | ABCD0102 | 2025-04-23T20:51:00 | 14 | Week 14 | 97 | 354 | Slightly severe | 2 | |
| 101 | ABCD0102 | 2025-04-24T19:23:00 | 14 | Week 14 | 98 | 354 | Slightly severe | 2 | |
| 101 | ABCD0102 | 2025-04-25T18:44:00 | 15 | Week 15 | 99 | 354 | Severe | 3 | |
| 101 | ABCD0102 | 2025-04-26T18:48:00 | 15 | Week 15 | 100 | 354 | Severe | 3 | |
| 101 | ABCD0102 | 2025-04-30T14:04:00 | 15 | Week 15 | 104 | 354 | Severe | 3 | |
| 101 | ABCD0102 | 2025-05-01T13:08:00 | 15 | Week 15 | 105 | 354 | Slightly severe | 2 | |
| 101 | ABCD0102 | 2025-05-02T09:40:00 | 16 | Week 16 | 106 | 354 | Not severe | 1 | |
| 101 | ABCD0102 | 2025-05-04T20:07:00 | 16 | Week 16 | 108 | 354 | Slightly severe | 2 | |
| 101 | ABCD0102 | 2025-05-05T19:17:00 | 16 | Week 16 | 109 | 354 | Slightly severe | 2 | |
| 101 | ABCD0102 | 2025-05-06T16:55:00 | 16 | Week 16 | 110 | 354 | Not severe | 1 | |
| 101 | ABCD0102 | 2025-05-07T18:16:00 | 16 | Week 16 | 111 | 354 | Slightly severe | 2 | |
| 101 | ABCD0102 | 2025-05-08T09:45:00 | 16 | Week 16 | 112 | 354 | Not severe | 1 | |
| 101 | ABCD0102 | 2025-05-09T21:46:00 | 17 | Week 17 | 113 | 354 | Slightly severe | 2 | |
| 101 | ABCD0102 | 2025-05-10T17:54:00 | 17 | Week 17 | 114 | 354 | Slightly severe | 2 | |
| 101 | ABCD0102 | 2025-05-11T22:10:00 | 17 | Week 17 | 115 | 354 | Slightly severe | 2 | |
| 101 | ABCD0102 | 2025-05-12T16:03:00 | 17 | Week 17 | 116 | 354 | Slightly severe | 2 | |
| 101 | ABCD0102 | 2025-05-13T16:51:00 | 17 | Week 17 | 117 | 354 | Slightly severe | 2 | |
| 101 | ABCD0102 | 2025-05-15T10:08:00 | 17 | Week 17 | 119 | 354 | Slightly severe | 2 | |
| 101 | ABCD0102 | 2025-05-19T16:08:00 | 18 | Week 18 | 123 | 354 | Slightly severe | 2 | |
| 101 | ABCD0102 | 2025-05-20T16:59:00 | 18 | Week 18 | 124 | 354 | Slightly severe | 2 | |
| 101 | ABCD0102 | 2025-05-21T19:34:00 | 18 | Week 18 | 125 | 354 | Slightly severe | 2 | |
| 101 | ABCD0102 | 2025-05-22T19:53:00 | 18 | Week 18 | 126 | 354 | Slightly severe | 2 | |
| 101 | ABCD0102 | 2025-05-23T17:50:00 | 19 | Week 19 | 127 | 354 | Slightly severe | 2 | |
| 101 | ABCD0102 | 2025-05-25T20:24:00 | 19 | Week 19 | 129 | 354 | Slightly severe | 2 | |
| 101 | ABCD0102 | 2025-05-26T14:53:00 | 19 | Week 19 | 130 | 354 | Not severe | 1 | |
| 101 | ABCD0102 | 2025-05-27T16:31:00 | 19 | Week 19 | 131 | 354 | Not severe | 1 | |
| 101 | ABCD0102 | 2025-05-28T15:13:00 | 19 | Week 19 | 132 | 354 | Not severe | 1 | |
| 101 | ABCD0102 | 2025-05-29T08:43:00 | 19 | Week 19 | 133 | 354 | Not severe | 1 | |
| 101 | ABCD0102 | 2025-05-30T21:46:00 | 20 | Week 20 | 134 | 354 | Not severe | 1 | |
| 101 | ABCD0102 | 2025-05-31T20:23:00 | 20 | Week 20 | 135 | 354 | |||
| 101 | ABCD0102 | 2025-06-02T18:46:00 | 20 | Week 20 | 137 | 354 | |||
| 101 | ABCD0102 | 2025-06-03T19:11:00 | 20 | Week 20 | 138 | 354 | |||
| 101 | ABCD0102 | 2025-06-04T18:58:00 | 20 | Week 20 | 139 | 354 | |||
| 101 | ABCD0102 | 2025-06-05T20:52:00 | 20 | Week 20 | 140 | 354 | |||
| 101 | ABCD0102 | 2025-06-06T17:41:00 | 21 | Week 21 | 141 | 354 |
Why does ADY not agree with AVISITN?
Is it because the subject came late for the visit?
Which one do you want to use when they disagree?
Thanks for your response. Its because we map the closet ady to that week.
Assuming I understood what you mean.
data have; infile cards truncover expandtabs dlm=' '; input USUBJID (PARAMCD ADTM) (:$40.) AVISITN AVISIT &$20. ADY EOTDY AVALC &$20. AVAL; cards; 101 ABCD0102 2025-01-20T12:54:00 1 Week 1 4 354 Slightly severe 2 101 ABCD0102 2025-01-21T07:52:00 1 Week 1 5 354 Slightly severe 2 101 ABCD0102 2025-01-22T07:16:00 1 Week 1 6 354 101 ABCD0102 2025-01-23T12:09:00 1 Week 1 7 354 101 ABCD0102 2025-01-24T17:15:00 2 Week 2 8 354 101 ABCD0102 2025-01-26T13:10:00 2 Week 2 10 354 Severe 3 101 ABCD0102 2025-01-28T11:09:00 2 Week 2 12 354 Severe 3 101 ABCD0102 2025-01-30T14:04:00 2 Week 2 14 354 Slightly severe 2 101 ABCD0102 2025-02-01T09:23:00 3 Week 3 16 354 Slightly severe 2 101 ABCD0102 2025-02-02T19:56:00 3 Week 3 17 354 Slightly severe 2 101 ABCD0102 2025-02-03T14:48:00 3 Week 3 18 354 Slightly severe 2 101 ABCD0102 2025-02-04T13:22:00 3 Week 3 19 354 Slightly severe 2 101 ABCD0102 2025-02-06T18:44:00 3 Week 3 21 354 Slightly severe 2 101 ABCD0102 2025-02-08T18:09:00 4 Week 4 23 354 Slightly severe 2 101 ABCD0102 2025-02-09T17:24:00 4 Week 4 24 354 Not severe 1 101 ABCD0102 2025-02-10T16:40:00 4 Week 4 25 354 Not severe 1 101 ABCD0102 2025-02-11T19:27:00 4 Week 4 26 354 Not severe 1 ; proc format; invalue fmt 1=1 2=2 3=3 4=4 5=5 6=6 7=7 8=8 9=9 10=10 11=11 12=12 13-15=13 16-18=14 19-21=15 22-24=16 25-27=17 28-30=18 ; data have2; set have; id=input(AVISITN,fmt.); run; proc sql; create table want as select * from have2 group by USUBJID ,PARAMCD ,id having AVAL =max(AVAL ); quit;
Nearly 200 sessions are now available on demand in the Innovate Hub.
Watch Now →Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.