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

fighting123_1-1603468042993.png

DATA vegas_new_e;
SET vegas_new_d;
ARRAY new(6)  f1 f2 f3 f4 f5 f6; /*Create new array facility 1 -6 and variables f1 - f6 by recode ‘yes’ as ‘1’ and ‘no’ as ‘0’*/
ARRAY old (6) pool--internet;
DO (i) = 1 TO 6;
IF old (i) = 'YES'  THEN new (i) = 1;
ELSE  new (i) = 0;
END;
SumFac = SUM( OF f1 - f6 ); /*create new variable SumFac to calculate the total sum of facilities score*/
PROC PRINT DATA=vegas_new_e;
TITLE 'vegas_new_e';
RUN;

why it isn't work

i have been run this before successfully  and when i close the programme and reopen it, it fails to work

1 ACCEPTED SOLUTION

Accepted Solutions
novinosrin
Tourmaline | Level 20

Hi @fighting123  A quick look at your code tells me this syntax error-

 

do (i)  --> this index variable should not be within parenthesis as this not an array reference. Hope this helps

View solution in original post

4 REPLIES 4
novinosrin
Tourmaline | Level 20

Hi @fighting123  A quick look at your code tells me this syntax error-

 

do (i)  --> this index variable should not be within parenthesis as this not an array reference. Hope this helps

ballardw
Super User

When the idea is to create dichotomous 1/0 coded variables you can simplify code. SAS comparisons like =, >  and so on will return a value of 1 for true and 0 for false. And when you have values in an array you can reference the entire array as "of arrayname(*)" in places where variable lists are allowed. This can be pretty useful if you may have to change the array definition. Then you do not have to change coding like "of f1-f6", the list would adjust automatically with the array definition.

So

DATA vegas_new_e;
   SET vegas_new_d;
   ARRAY new(6)  f1 f2 f3 f4 f5 f6; /*Create new array facility 1 -6 and variables f1 - f6 by recode ‘yes’ as ‘1’ and ‘no’ as ‘0’*/
   ARRAY old (6) pool--internet;
   DO i = 1 TO 6;
      new (i) = ( old(i) = 'YES');
   END;
   SumFac = sum( of new(*) );
run;

 

By the way, if you know that you need this type of recoding it is easily done at read time if you use a data step to read the data. Custom informats can be created to deal with expected values.

Consider the following code. Proc format creates an informat named Yesno that will yield numeric values of 1 for Yes and 0 for No, spelled in a number of ways. The UPCASE option uses upcased versions of the text read so YES, Yes, yES and all those permutations are treated the same. Similar for lazy data entry types that may only enter a single Y. Similar for No. The Blank assigned to .N creates a special missing value that says "nothing was entered", when you look at data the N in a numeric field may be helpful. Note, this may address the issue that the array recoding doesn't of what to do with a blank value. Do you really want 0? Additionally the other=_error_ says any other value encountered is invalid data will generate such a message with the typical diagnostics.

Depending on your browser settings you may question why one of the values gets reported as an error. Think Capital O versus numeric 0 as a not uncommon data entry issue.

 

proc format;
invalue yesno (upcase)
'YES','Y' = 1
'NO','N'  = 0
' '       = .n
other = _error_
;
run;

data example;
   infile datalines dlm=',' missover;
   informat x yesno.;
   input id x;
datalines;
1,YES
2,Yes
3,yes
4,y
5,NO
6,No
7,no
8,N0
9,N
10,n
11,false
12,,
;

I have a similar yesno informat available to handle many values that I want to manipulate as 1/0. You could add TRUE and FALSE or similar values. The special missing and the other = _error_ are not required but may be helpful. Or just the yes/no and other = . to set anything except the expected values to missing. There are a variety of approaches available. I use many of these informats for expected lists of values because several of my data sources will add values without documenting or referencing them.

Another useful option is a list of values and _same_ as the value, which means the incoming value is kept with an other=_error_ which tells you an expected value occurs. This can work with character values as well.

proc format;
invalue $Namelist (upcase)
"FRED","MIKE","MARY" = _same_
other = _error_
;
run;

data example;
   informat Name $namelist.;
   input name;
datalines;
fred
Fred
Mike
MIKE
mike
Mary
John
nike
;

Note that the capitalization of the name values are not changed but the value is validated. You could force the consistent case by using value pairs

"MIKE" = "Mike"

for example.

fighting123
Fluorite | Level 6
thank you so much!!!! it is very detailed

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!

Mastering the WHERE Clause in PROC SQL

SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 4 replies
  • 634 views
  • 3 likes
  • 4 in conversation