I hope you can see the log output. Ok. Two questions.
(1) The log output sas that missing values were generated on line 1187. If you go the bottom of the posted code you will see 1187 pulled out by itself and the column locations are marked by |&| following the noted column. So i know that there was one record with a missing value for A2WEIGHT and so '.' should have been the result for vbacwk{i}, i=1 to 7 and it was. My question is why was three missing value notes reported. I've seen these messages but i've nerver understood them except for the fact that a missing value was assigned to the result variable for some record in the dataset. Please help me understand.
(2) Now look at lines 1186, 87, and 88. My intention was that if the else if statement is true, both 1187 and 1188 are executed. However, if the else if is false, both 1187 and 1188 are not executed.
These lines execute correctly, as near as i can tell, but why shouldn't i have had to write this instead
1186 else if (valcwk{i} ge 1 and valhwk{i} ge 1) then do
1187 vbacwk{i}=((valcwk{i}/2)*(9.0/A2WEIGHT))-(0.02*valhwk{i});
1188 if (vbacwk{i} le 0.0 and vbacwk{i} gt -1.) then vbacwk{i}=0.0;
end;
When i tried that i got this
2335 vbacwk{i}=((valcwk{i}/2)*(9.0/A2WEIGHT))-(0.02*valhwk{i});
-
73
76
ERROR 73-322: Expecting an =.
ERROR 76-322: Syntax error, statement will be ignored.
Why isn't a do required? I want conditionally execute both 1187 and 1188. Why the error?
Thanks, Gene Maguin
1173 * COMPUTE WOMEN'S DAILY BAC BASED ON TYPICAL DAILY DRINKS AND WEIGHT;
1174 * NOT SURE OF THE EXACT SOURCE BUT SOMEBODY WIDMARK IS NAMED;
1175 * [(c/2)*(GC/w)] -(B60*t), where c = total standard drinks consumed,
1176 GC = gender constant (9.0 for women, 7.5 for men), w = weight in pounds,
1177 B60 = hourly rate of metabolism of alcohol (estimated at .02), and
1178 t = total drinking hours;
1179 * PER CRAIG (ABOUT 08.26.2021) COMPUTE BAC AS .p IF DRINKS > 1 AND HOURS=0
1180 * OR IF DRINKS = 0 AND HOURS > 1;
1181 * RECODE TO .s IF BAC LE 0.0;
>>>> array valcwk{i} defined above this section.
1182 array valhwk{7} A2ALCH1-A2ALCH7;
1183 array vbacwk{7} A2BAC1-A2BAC7;
1184 do i=1 to 7;
1185 if (valcwk{i} eq 0 and valhwk{i} eq 0) then vbacwk{i}=.s;
1186 else if (valcwk{i} ge 1 and valhwk{i} ge 1) then
1187 vbacwk{i}=((valcwk{i}/2)*(9.0/A2WEIGHT))-(0.02*valhwk{i});
1188 if (vbacwk{i} le 0.0 and vbacwk{i} gt -1.) then vbacwk{i}=0.0;
1189 else if (valcwk{i} eq .p or valhwk{i} eq .p) then vbacwk{i}=.p;
1190 else if (valcwk{i} eq 0 and valhwk{i} gt 0) then vbacwk{i}=.p;
1191 else if (valcwk{i} gt 0 and valhwk{i} eq 0) then vbacwk{i}=.p;
1192 end;
1193 run;
NOTE: Missing values were generated as a result of performing an operation on missing values.
Each place is given by: (Number of times) at (Line):(Column).
1 at 1187:32 1 at 1187:37 1 at 1187:48
1187 vbacwk{i}=((valcwk{i}/2)|&|*(9.0|&|/A2WEIGHT))|&|-(0.02*valhwk{i});
if you want multiple lines of code executed after the do, it requires a semicolon.
If .. then do;
Code to execute….
End;
Otherwise, it only does what comes after the do. It simplifies things if you only have one action.
@emaguin wrote:
I hope you can see the log output. Ok. Two questions.
(1) The log output sas that missing values were generated on line 1187. If you go the bottom of the posted code you will see 1187 pulled out by itself and the column locations are marked by |&| following the noted column. So i know that there was one record with a missing value for A2WEIGHT and so '.' should have been the result for vbacwk{i}, i=1 to 7 and it was. My question is why was three missing value notes reported. I've seen these messages but i've nerver understood them except for the fact that a missing value was assigned to the result variable for some record in the dataset. Please help me understand.
(2) Now look at lines 1186, 87, and 88. My intention was that if the else if statement is true, both 1187 and 1188 are executed. However, if the else if is false, both 1187 and 1188 are not executed.
These lines execute correctly, as near as i can tell, but why shouldn't i have had to write this instead
1186 else if (valcwk{i} ge 1 and valhwk{i} ge 1) then do
1187 vbacwk{i}=((valcwk{i}/2)*(9.0/A2WEIGHT))-(0.02*valhwk{i});
1188 if (vbacwk{i} le 0.0 and vbacwk{i} gt -1.) then vbacwk{i}=0.0;
end;
When i tried that i got this
2335 vbacwk{i}=((valcwk{i}/2)*(9.0/A2WEIGHT))-(0.02*valhwk{i});
-
73
76
ERROR 73-322: Expecting an =.ERROR 76-322: Syntax error, statement will be ignored.
Why isn't a do required? I want conditionally execute both 1187 and 1188. Why the error?
Thanks, Gene Maguin
1173 * COMPUTE WOMEN'S DAILY BAC BASED ON TYPICAL DAILY DRINKS AND WEIGHT; 1174 * NOT SURE OF THE EXACT SOURCE BUT SOMEBODY WIDMARK IS NAMED; 1175 * [(c/2)*(GC/w)] -(B60*t), where c = total standard drinks consumed, 1176 GC = gender constant (9.0 for women, 7.5 for men), w = weight in pounds, 1177 B60 = hourly rate of metabolism of alcohol (estimated at .02), and 1178 t = total drinking hours; 1179 * PER CRAIG (ABOUT 08.26.2021) COMPUTE BAC AS .p IF DRINKS > 1 AND HOURS=0 1180 * OR IF DRINKS = 0 AND HOURS > 1; 1181 * RECODE TO .s IF BAC LE 0.0; >>>> array valcwk{i} defined above this section. 1182 array valhwk{7} A2ALCH1-A2ALCH7; 1183 array vbacwk{7} A2BAC1-A2BAC7; 1184 do i=1 to 7; 1185 if (valcwk{i} eq 0 and valhwk{i} eq 0) then vbacwk{i}=.s; 1186 else if (valcwk{i} ge 1 and valhwk{i} ge 1) then 1187 vbacwk{i}=((valcwk{i}/2)*(9.0/A2WEIGHT))-(0.02*valhwk{i}); 1188 if (vbacwk{i} le 0.0 and vbacwk{i} gt -1.) then vbacwk{i}=0.0; 1189 else if (valcwk{i} eq .p or valhwk{i} eq .p) then vbacwk{i}=.p; 1190 else if (valcwk{i} eq 0 and valhwk{i} gt 0) then vbacwk{i}=.p; 1191 else if (valcwk{i} gt 0 and valhwk{i} eq 0) then vbacwk{i}=.p; 1192 end; 1193 run; NOTE: Missing values were generated as a result of performing an operation on missing values. Each place is given by: (Number of times) at (Line):(Column). 1 at 1187:32 1 at 1187:37 1 at 1187:48 1187 vbacwk{i}=((valcwk{i}/2)|&|*(9.0|&|/A2WEIGHT))|&|-(0.02*valhwk{i});
DO is required, as is a semi-colon after DO (which you don't have)
SAS has many different flavors of DO statements.
Looks like you intended to run a the bare DO statement.
if x then do;
statement1;
statement2;
end;
But because of the missing semi-colon after the DO instead you ran a version of aniteration DO statement, which can have many forms:
do i=1 to 10;
do i=1,3,4,5;
do i=1,5 to 10,13 ;
But instead of multiple values you only had one value.
if (valcwk{i} ge 1 and valhwk{i} ge 1) then do vbacwk{i}=((valcwk{i}/2)*(9.0/A2WEIGHT))-(0.02*valhwk{i});
In your code the iteration variable is a reference to an array, vbacwk{i}, and SAS syntax does not allow that.
Here is clearer example that demonstrates the coding error:
81 data _null_; 82 set sashelp.class; 83 array n _numeric_; 84 do n[1]= 5-6 ; - 73 76 ERROR 73-322: Expecting an =. ERROR 76-322: Syntax error, statement will be ignored. 85 put n[1]=; 86 end; 87 run;
It's finally time to hack! Remember to visit the SAS Hacker's Hub regularly for news and updates.
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.