Calcite | Level 5

## YRDIF-ROUND-IF THEN statements help

The Quality of Life Form (QUL) was administered regularly to the patients enrolled in the National Interstitial Cystistis Data Base Study. The resulting quality of life data are stored in a permanent SAS data set called qul . In summary, your job is to use the quality of life data to create the following five-by-three table of frequency counts:

where years is defined as the number of years (rounded) between a patient's first and last visits, and score is defined as Better, NoChange, or Worse depending on the change in the patient's reply to the first question on the QUL form (qul_1) between a patient's first and last visits. Here are the specific requirements for the problem:

·        Use just one DATA step to process the data (by subj).

·        Use the YRDIF and ROUND functions to determine the number of years (rounded to the nearest integer) between the patient's first visit date and last visit date (v_date). (Note that each observation in the QUL data set corresponds to just one patient visit date. Therefore, you will need to use a RETAIN statement to keep track of the patient's first visit data.)

·        First, calculate the change in the patient's score for qul_1 by subtracting the qul_1 value for the patient's first visit from the qul_1 value from the patient's last visit. Then, if the change is negative, set score to equal Better; if the change is positive, set score to equal Worse; and if the change is 0, set score to equal NoChange.

·        Use years and score to create the table.

Is there sufficient evidence to conclude that there is an association between years and score? Justify your answer based on your output.

Here is my code: needs help so many errors

/**************************************************************

**************************************************************/
OPTIONS NODATE NONUMBER;

PROC SORT DATA = stat483.qul OUT= qul;
by subj;
RUN;

DATA gul;
INPUT subj v_type v_date mmddyy8. r_id qul_1-qul_11d;
RETAIN firstv_date;

firstv_date = first.v_date;
lastv_date = last.v_date;
years=yrdif(firstv_date,lastv_date, 'act/act');

score=((qul_1 lastv_date - qul_1 firstv_date);
IF change - THEN score = 'better';
ELSE IF change + THEN score = 'Worse';
ELSE IF change 0 THEN score = 'NoChange';
OUTPUT;
RUN;

PROC FREQ data=qul;
by subj
TABLE Years*Score/CMH NOPERCENT NOCOL;
RUN;

1 ACCEPTED SOLUTION

Accepted Solutions
Super User

## Re: YRDIF-ROUND-IF THEN statements help

If your code throws errors you need to share them as we can't tell what they might be.

Run the code, go to the log and copy the text of the submitted code along with all notes, messages and errors. On the forum open a text box by clicking on the </> icon above the message window and paste the copied text.

The text box is important because the message windows on the forum will reformat pasted text and many of the errors will cause SAS to place diagnostic characters in the log. The reformatted text will typically move those diagnostics so that the position cannot be determined.

I suspect one of your errors is the INPUT statement. To use an Input that way there has to be text to read by the program. The text could be in an external file, which would require an INFILE statement to identify it, or a DATALINES block where the data step contains the text to read. If you want to use data from an existing data set then you use a SET statement to identify the data set.

I am guessing that you actually want : Set qul; as the data set you just sorted.

To use the First.variable and Last.variable constructs there must be a BY statement using the variable name.

The First.variable return true/false numeric values of 1/0. So your Yrdif call is attempting to use 1 and 0, which would be 2Jan1960 and 1Jan1960 respectively (SAS dates are the number of days from 1Jan1960).

So that indicates you likely want something like (AFTER you add the by statement): If first.vdate then firstv_date=vdate;

Similar for the last date.

You will need to do similar to Retain and calculate a difference for the scores.

And only calculate the year difference after you have the last date.

This will make no sense to SAS:

```IF change - THEN score = 'better';
ELSE IF change + THEN score = 'Worse';
ELSE IF change 0 THEN score = 'NoChange';```

You have to provide a comparison operator such a =  > or < (EQ GT LT GE (greater than or equal) LE ) and a value

Maybe

```If change < 0 then score = 'Better';
else if change > 0 then score= 'Worse';
else if change = 0 then score= 'No Change';```

Caveat: your score variable will have a length of 6 characters and will truncate "No Change" to 6 as well. When using character variables it is a good idea to explicitly assign a length large enough to hold the longest expected value before use:

Length score \$ 9;

3 REPLIES 3
Diamond | Level 26

## Re: YRDIF-ROUND-IF THEN statements help

Here is my code: needs help so many errors

It would be helpful if you told us what errors were found. We could, go through the code and find them ourselves (and probably miss some), but since you already know the errors, SHOW US. In fact, in the future, whenever you have ERRORs in the log, we need to see the LOG. SHOW US.

Please, provide us the ENTIRE log for this SAS data step. That is: we want to see 100% of the log, every single character, exactly as you see it. Do not pick and choose parts of the log to show us, and not show us other parts. Copy the log as text, and then paste it into the window that appears when you click on the </> icon. DO NOT SKIP THIS STEP.

--
Paige Miller
Super User

## Re: YRDIF-ROUND-IF THEN statements help

You put your name and homework assignment for your final exam on the internet?
Glad to see professors are allowing more open book exams these days.

Same offer as last time, comment your code with what you think it's doing and I'll be happy to help you debug your code.

Spoiler

@mpc5 wrote:

The Quality of Life Form (QUL) was administered regularly to the patients enrolled in the National Interstitial Cystistis Data Base Study. The resulting quality of life data are stored in a permanent SAS data set called qul . In summary, your job is to use the quality of life data to create the following five-by-three table of frequency counts:

where years is defined as the number of years (rounded) between a patient's first and last visits, and score is defined as Better, NoChange, or Worse depending on the change in the patient's reply to the first question on the QUL form (qul_1) between a patient's first and last visits. Here are the specific requirements for the problem:

·        Use just one DATA step to process the data (by subj).

·        Use the YRDIF and ROUND functions to determine the number of years (rounded to the nearest integer) between the patient's first visit date and last visit date (v_date). (Note that each observation in the QUL data set corresponds to just one patient visit date. Therefore, you will need to use a RETAIN statement to keep track of the patient's first visit data.)

·        First, calculate the change in the patient's score for qul_1 by subtracting the qul_1 value for the patient's first visit from the qul_1 value from the patient's last visit. Then, if the change is negative, set score to equal Better; if the change is positive, set score to equal Worse; and if the change is 0, set score to equal NoChange.

·        Use years and score to create the table.

Is there sufficient evidence to conclude that there is an association between years and score? Justify your answer based on your output.

Here is my code: needs help so many errors

/**************************************************************
Written by: Michelle Calderon
Final Exam Question 5
**************************************************************/
OPTIONS NODATE NONUMBER;

PROC SORT DATA = stat483.qul OUT= qul;
by subj;
RUN;

DATA gul;
INPUT subj v_type v_date mmddyy8. r_id qul_1-qul_11d;
RETAIN firstv_date;

firstv_date = first.v_date;
lastv_date = last.v_date;
years=yrdif(firstv_date,lastv_date, 'act/act');

score=((qul_1 lastv_date - qul_1 firstv_date);
IF change - THEN score = 'better';
ELSE IF change + THEN score = 'Worse';
ELSE IF change 0 THEN score = 'NoChange';
OUTPUT;
RUN;

PROC FREQ data=qul;
by subj
TABLE Years*Score/CMH NOPERCENT NOCOL;
RUN;

Super User

## Re: YRDIF-ROUND-IF THEN statements help

If your code throws errors you need to share them as we can't tell what they might be.

Run the code, go to the log and copy the text of the submitted code along with all notes, messages and errors. On the forum open a text box by clicking on the </> icon above the message window and paste the copied text.

The text box is important because the message windows on the forum will reformat pasted text and many of the errors will cause SAS to place diagnostic characters in the log. The reformatted text will typically move those diagnostics so that the position cannot be determined.

I suspect one of your errors is the INPUT statement. To use an Input that way there has to be text to read by the program. The text could be in an external file, which would require an INFILE statement to identify it, or a DATALINES block where the data step contains the text to read. If you want to use data from an existing data set then you use a SET statement to identify the data set.

I am guessing that you actually want : Set qul; as the data set you just sorted.

To use the First.variable and Last.variable constructs there must be a BY statement using the variable name.

The First.variable return true/false numeric values of 1/0. So your Yrdif call is attempting to use 1 and 0, which would be 2Jan1960 and 1Jan1960 respectively (SAS dates are the number of days from 1Jan1960).

So that indicates you likely want something like (AFTER you add the by statement): If first.vdate then firstv_date=vdate;

Similar for the last date.

You will need to do similar to Retain and calculate a difference for the scores.

And only calculate the year difference after you have the last date.

This will make no sense to SAS:

```IF change - THEN score = 'better';
ELSE IF change + THEN score = 'Worse';
ELSE IF change 0 THEN score = 'NoChange';```

You have to provide a comparison operator such a =  > or < (EQ GT LT GE (greater than or equal) LE ) and a value

Maybe

```If change < 0 then score = 'Better';
else if change > 0 then score= 'Worse';
else if change = 0 then score= 'No Change';```

Caveat: your score variable will have a length of 6 characters and will truncate "No Change" to 6 as well. When using character variables it is a good idea to explicitly assign a length large enough to hold the longest expected value before use:

Length score \$ 9;

Discussion stats
• 3 replies
• 629 views
• 1 like
• 4 in conversation