BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
nwang5
Obsidian | Level 7

Is there any easier way to do this? Thanks! 

all variables included:0, 1 , and missing.

if (R9MEMRY=1 or R9MEMRYE=1) then do;

 if (R10ALZHE=1 or R10ALZHEE=1 or R10DEMEN=1 or R10DEMENE=1) then adrd9=1;
else if ((R10ALZHE=. and R10ALZHEE=. and R10DEMEN=. and R10DEMENE=.) and (R11ALZHE=1 or R11ALZHEE=1 or R11DEMEN=1 or R11DEMENE=1)) then adrd9=1;
else if ((R10ALZHE=. and R10ALZHEE=. and R10DEMEN=. and R10DEMENE=.) and (R11ALZHE=. and R11ALZHEE=. and R11DEMEN=. and R11DEMENE=.) and (R12ALZHE=1 or R12ALZHEE=1 or R12DEMEN=1 or R12DEMENE=1)) then adrd9=1;
else if ((R10ALZHE=. and R10ALZHEE=. and R10DEMEN=. and R10DEMENE=.) and (R11ALZHE=. and R11ALZHEE=. and R11DEMEN=. and R11DEMENE=.)
and (R12ALZHE=. and R12ALZHEE=. and R12DEMEN=. and R12DEMENE=.) ) then adrd9=1;
else adrd9=0;
end;

ObsR9MEMRYER9MEMRYR10ALZHER10ALZHEER10DEMENR10DEMENER11ALZHER11ALZHEER11DEMENR11DEMENER12ALZHER12ALZHEER12DEMENR12DEMENEadrd9
10.No0.No1.Yes1.Yes.S=Skip1.Yes1.Yes1.Yes.S=Skip1.Yes....0
20.No0.No0.No0.No0.No0.No0.No0.No0.No0.No0.No0.No0.No0.No0
30.No0.No0.No0.No0.No0.No0.No0.No0.No0.No0.No0.No0.No0.No0
40.No0.No0.No0.No0.No0.No........0
50.No0.No0.No0.No0.No0.No0.No0.No0.No0.No0.No0.No0.No0.No0
61.Yes1.Yes0.No0.No0.No0.No0.No0.No0.No0.No1.Yes1.Yes.S=Skip1.Yes0
70.No0.No.S=Skip.S=Skip.S=Skip.S=Skip1.Yes0.No0.No0.No1.Yes0.No0.No0.No0
80.No0.No0.No0.No0.No0.No0.No0.No0.No0.No0.No0.No0.No0.No0
91.Yes1.Yes.S=Skip.S=Skip.S=Skip.S=Skip1.Yes0.No0.No0.No0.No1.Yes0.No0.No1
100.No0.No0.No0.No0.No0.No0.No0.No0.No0.No0.No0.No0.No0.No0
110.No0.No0.No0.No0.No0.No0.No0.No0.No0.No0.No0.No0.No0.No0
1 ACCEPTED SOLUTION

Accepted Solutions
FreelanceReinh
Jade | Level 19

@nwang5 wrote:

if ((R9MEMRY=1 or R9MEMRYE=1) and adrd10=1) then adrd9=1;
else if ((R9MEMRY=1 or R9MEMRYE=1) and adrd10=. and adrd11=1) then adrd9=1;
else if ((R9MEMRY=1 or R9MEMRYE=1) and adrd10=. and adrd11=. and adrd12=1) then adrd9=1;
else if ((R9MEMRY=1 or R9MEMRYE=1) and adrd10=. and adrd11=. and adrd12=. and  adrd13=1) then adrd9=1;
else if ((R9MEMRY=1 or R9MEMRYE=1) and adrd10=. and adrd11=. and adrd12=. and  adrd13=.) then adrd9=1;

else adrd9=0;

id R9MEMRY R9MEMRY ADRD10 ADRD11 ADRD12 ADRD13 adrd9(expected)
1 1 . 0 . . 1 0
2 1 . 1 . 1 . 1
3 0 . 1 . . 1 0
4 . 0 . . 1 . 1
5 1 1 . 1     1
6 0 . . 0 0 1 0

 


According to your SAS code (and reading the second "R9MEMRY" column as "R9MEMRYE"), adrd9 should be 0 for id=4.

 

The part of the condition regarding adrd10-adrd13 can be simplified with the COALESCE function regardless of the possible values of these four variables, except if these include special missing values:

adrd9=(R9MEMRY=1 | R9MEMRYE=1) & coalesce(of adrd10-adrd13) in (1,.);

If the only possible non-missing values of R9MEMRY and R9MEMRYE are 0 and 1, you can simplify this slightly further:

adrd9=(R9MEMRY | R9MEMRYE) & coalesce(of adrd10-adrd13) in (1,.);

View solution in original post

6 REPLIES 6
Tom
Super User Tom
Super User

Kind of depends on what are the set of possible values for those 4 variables.  Why not build a truth table a look at it?

 

You seem to be setting ADRD9 to either 0 or 1.  In that case you just set assign the result of a boolean expression to the variable instead.

adrd9 = ( ... your boolean expression here ) ;

When it is TRUE the value will be 1.  When it is FALSE the value will be 0.

ballardw
Super User

Factoring out a common expression can at least make the code a bit more readable.

if (R9MEMRY=1 or R9MEMRYE=1) then do;
   if adrd10=1 then adrd9=1;
   else if ( adrd10=. and adrd11=1) then adrd9=1;
   else if ( adrd10=. and adrd11=. and adrd12=1) then adrd9=1;
   else if ( adrd10=. and adrd11=. and adrd12=. and  adrd13=1) then adrd9=1;
   else if ( adrd10=. and adrd11=. and adrd12=. and  adrd13=.) then adrd9=1;
   else adrd9=0;
end;
else adrd9=0;

However providing rules and information about the variables is better.

For instance if the variables adrd10 through adrd13 can only have the values 1 or missing and you want to set ardrd=1 when  only one of them is =1 or all are missing this could reduce to :

if (R9MEMRY=1 or R9MEMRYE=1) then adrd9= (sum (of adrd10-adrd13) le 1);
else adrd9=0;

 

Since we do not have all of the possible values of adrd10 through adrd13 and there is no actual rule about use of those variables provided then it is pretty hard to recommend a generic "easier".

 

If you have variables that are 1/0/missing or 1/missing then you can tell things like how many are = 1 with the SUM function; if any are =1 with the MAX function; the NMISS function will return the number of missing; the Range function will return 0 if all of the non-missing values have the same numeric value (all 1 or all 0 for example). So these functions may with care provide lots of information.

 

Caution: Do pay attention to the OF in the sum(of var1-varn) syntax. If you miss the OF, which indicates "use a list of values", the result will be that of the arithmetic var1-varn which seldom is the same. Also with this syntax all of the variables have to be sequentially numbered with no gaps. There are ways around gaps by using multiple sequences separated by commas or just using all of the variable names explicitly.

 

FreelanceReinh
Jade | Level 19

@nwang5 wrote:

if ((R9MEMRY=1 or R9MEMRYE=1) and adrd10=1) then adrd9=1;
else if ((R9MEMRY=1 or R9MEMRYE=1) and adrd10=. and adrd11=1) then adrd9=1;
else if ((R9MEMRY=1 or R9MEMRYE=1) and adrd10=. and adrd11=. and adrd12=1) then adrd9=1;
else if ((R9MEMRY=1 or R9MEMRYE=1) and adrd10=. and adrd11=. and adrd12=. and  adrd13=1) then adrd9=1;
else if ((R9MEMRY=1 or R9MEMRYE=1) and adrd10=. and adrd11=. and adrd12=. and  adrd13=.) then adrd9=1;

else adrd9=0;

id R9MEMRY R9MEMRY ADRD10 ADRD11 ADRD12 ADRD13 adrd9(expected)
1 1 . 0 . . 1 0
2 1 . 1 . 1 . 1
3 0 . 1 . . 1 0
4 . 0 . . 1 . 1
5 1 1 . 1     1
6 0 . . 0 0 1 0

 


According to your SAS code (and reading the second "R9MEMRY" column as "R9MEMRYE"), adrd9 should be 0 for id=4.

 

The part of the condition regarding adrd10-adrd13 can be simplified with the COALESCE function regardless of the possible values of these four variables, except if these include special missing values:

adrd9=(R9MEMRY=1 | R9MEMRYE=1) & coalesce(of adrd10-adrd13) in (1,.);

If the only possible non-missing values of R9MEMRY and R9MEMRYE are 0 and 1, you can simplify this slightly further:

adrd9=(R9MEMRY | R9MEMRYE) & coalesce(of adrd10-adrd13) in (1,.);
ballardw
Super User

Here is an example of a data set that builds ALL of the combinations of your independent variables and what I think you intend, since you do not have a clear rule stated about how to caculate the ardr9. If all 729 results match your expectations then the assignment code is "easier".

if (R9MEMRY=1 or R9MEMRYE=1) then do;
   if adrd10=1 then adrd9=1;
   else if ( adrd10=. and adrd11=1) then adrd9=1;
   else if ( adrd10=. and adrd11=. and adrd12=1) then adrd9=1;
   else if ( adrd10=. and adrd11=. and adrd12=. and  adrd13=1) then adrd9=1;
   else if ( adrd10=. and adrd11=. and adrd12=. and  adrd13=.) then adrd9=1;
   else adrd9=0;
end;
else adrd9=0;


if (R9MEMRY=1 or R9MEMRYE=1) then adrd9= (sum (of adrd10-adrd13) le 1);
else adrd9=0;

data example;
  do R9MEMRY=.,0,1;
  do R9MEMRYe=.,0,1;
  do adrd10= .,0,1;
  do adrd11= .,0,1;
  do adrd12= .,0,1;
  do adrd13= .,0,1;
      if (R9MEMRY=1 or R9MEMRYE=1) then adrd9= (range (of adrd10-adrd13)= 0 and max(of adrd10-adrd13)=1);
      else adrd9=0;
      output;
  end;
  end;
  end;
  end;
  end;
  end;
run;
  
ballardw
Super User

So, why the change in variables and logic? You  are making it appear as if multiple people completely ignored your question and posted random next to meaningless code. Also, you still are not stating any rule as to what the code is supposed to be doing so how could we know an "easier" way when we don't even know what this is supposed to do.
Did you read any of the bit I showed about how to use summary functions such as MAX, SUM to shorten code like
if (R10ALZHE=1 or R10ALZHEE=1 or R10DEMEN=1 or R10DEMENE=1)


@nwang5 wrote:

Is there any easier way to do this? Thanks! 

all variables included:0, 1 , and missing.

if (R9MEMRY=1 or R9MEMRYE=1) then do;

 if (R10ALZHE=1 or R10ALZHEE=1 or R10DEMEN=1 or R10DEMENE=1) then adrd9=1;
else if ((R10ALZHE=. and R10ALZHEE=. and R10DEMEN=. and R10DEMENE=.) and (R11ALZHE=1 or R11ALZHEE=1 or R11DEMEN=1 or R11DEMENE=1)) then adrd9=1;
else if ((R10ALZHE=. and R10ALZHEE=. and R10DEMEN=. and R10DEMENE=.) and (R11ALZHE=. and R11ALZHEE=. and R11DEMEN=. and R11DEMENE=.) and (R12ALZHE=1 or R12ALZHEE=1 or R12DEMEN=1 or R12DEMENE=1)) then adrd9=1;
else if ((R10ALZHE=. and R10ALZHEE=. and R10DEMEN=. and R10DEMENE=.) and (R11ALZHE=. and R11ALZHEE=. and R11DEMEN=. and R11DEMENE=.)
and (R12ALZHE=. and R12ALZHEE=. and R12DEMEN=. and R12DEMENE=.) ) then adrd9=1;
else adrd9=0;
end;

Obs R9MEMRYE R9MEMRY R10ALZHE R10ALZHEE R10DEMEN R10DEMENE R11ALZHE R11ALZHEE R11DEMEN R11DEMENE R12ALZHE R12ALZHEE R12DEMEN R12DEMENE adrd9
1 0.No 0.No 1.Yes 1.Yes .S=Skip 1.Yes 1.Yes 1.Yes .S=Skip 1.Yes . . . . 0
2 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0
3 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0
4 0.No 0.No 0.No 0.No 0.No 0.No . . . . . . . . 0
5 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0
6 1.Yes 1.Yes 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0.No 1.Yes 1.Yes .S=Skip 1.Yes 0
7 0.No 0.No .S=Skip .S=Skip .S=Skip .S=Skip 1.Yes 0.No 0.No 0.No 1.Yes 0.No 0.No 0.No 0
8 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0
9 1.Yes 1.Yes .S=Skip .S=Skip .S=Skip .S=Skip 1.Yes 0.No 0.No 0.No 0.No 1.Yes 0.No 0.No 1
10 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0
11 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0.No 0

 

nwang5
Obsidian | Level 7
Sorry for the lots of changes. This is original data I use. I read all the responses carefully and tried to use the codes.

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

How to Concatenate Values

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 6 replies
  • 1503 views
  • 1 like
  • 4 in conversation