BookmarkSubscribeRSS Feed
shonn2nd
Fluorite | Level 6

Not sure why if/then statement can't recode a character variable. My code doesn't work. Can anyone hep me? Thanks.

 

data mydata;
input film $ rating;
datalines;
1 2.8
1 3.8
1 4.4
1 2.9
1 2.3
2 2.7
2 3.8
2 3.3
2 4.0
2 4.2
;
run;

 

data mydata;
set mydata;
if film = "1" then filmname = "batman";
else if film = "2" then filmname = "goodwillhunting";
run;

 

10 REPLIES 10
sbjwhl
SAS Employee

Try below code:

 

data mydata1;
length film $16.; /* goodwillhunting exceeds 8 bytes long, so change the column length to 16 */
set mydata;
if film = "1" then film = "batman"; /* recode the values for film variable */
else if film = "2" then film = "goodwillhunting";
rename film=filmname; /* rename film to filmnale if you would like the variable as filmname */
run;

shonn2nd
Fluorite | Level 6

Hello sbjwhl,

 

Thank you for the help, but I don't know why It doesn't work. I think I forgot to tell an information here.

Below is the original dataset when all the variables are still numeric:

data mydata;
input film rating; *film is numeric;
datalines;
1 2.8
1 3.8
1 4.4
1 2.9
1 2.3
2 2.7
2 3.8
2 3.3
2 4.0
2 4.2
;
run;

then I convert "film" to character variable by creating film1 variable:

 

data mydata;
set mydata;
film1 = put(film, 6.);
run; 

then I started to use the approach you suggested:

data mydata;
length film1 $16.;
set mydata;
if film1 = "1" then film1 = "batman";
else if film1 = "2" then film1 = "goodwillhunting";
run;

But it doesn't work. Film1 is still 1 and 2. Do you know why? Thanks.

Astounding
PROC Star

The length of FILMNAME is the key issue here.  Since "batman" is the first value assigned, it receives a length of $ 6 (not long enough).  Try:

 

data mydata;
   set mydata;
   length filmname $ 15;
   if film = "1" then filmname = "batman";
   else if film = "2" then filmname = "goodwillhunting";
run;
shonn2nd
Fluorite | Level 6

Hello Astounding,

 

Thank you for the help, but I don't know why It doesn't work. I think I forgot to tell an information here.

Below is the original dataset when all the variables are still numeric:

data mydata;
input film rating; *film is numeric;
datalines;
1 2.8
1 3.8
1 4.4
1 2.9
1 2.3
2 2.7
2 3.8
2 3.3
2 4.0
2 4.2
;
run;

then I convert "film" to character variable by creating film1 variable:

 

data mydata;
set mydata;
film1 = put(film, 6.);
run; 

then I started to use the approach you suggested:

data mydata;
set mydata; length filmname $15; if film1 = "1" then filmname = "batman"; else if film1 = "2" then filmname = "goodwillhunting"; run;

But it doesn't work. filmname is empty. Do you know why? Thanks.

Astounding
PROC Star

I know why, but don't bother fixing it.  Just use FILM instead of FILM1:

 

if film=1 then filmname = "batman";

shonn2nd
Fluorite | Level 6

Thank you. Do you think the main issue lies in the process of converting numeric variable to character variable? Since when I checked ViewTable, film1 is more like centered instead of right-aligned like other char variables.

Tom
Super User Tom
Super User

@shonn2nd wrote:

Thank you. Do you think the main issue lies in the process of converting numeric variable to character variable? Since when I checked ViewTable, film1 is more like centered instead of right-aligned like other char variables.


Exactly.  You told it to convert it to a six character string.  So the value 1 was converted to '     1' and not '1'.

You could change how you create the character variable to make it left aligned.

Examples:

film1=put(film,6.-L);
film1=left(put(film,6.));
shonn2nd
Fluorite | Level 6

Hi Tom,

 

Thank you for pointing that out! After I change 6. to 1. and the issue is solved:

data mydata;
set mydata;
film1 = put(film, 1.); *the key is here;
run;

then

data mydata;
length filmname & 16.;
set mydata;
if film1= '1' then filmname = 'batman';
else if film1 = '2' then filmname = 'goodwillhunting';
run;

Smiley Happy

andreas_lds
Jade | Level 19

Using a format for re-coding is the recommended way. The benefits are:

  • less code in the data step
  • the mapping can be read from file, thus you don't have to change code if a misspelling is found

 

ballardw
Super User

For many purposes displaying another value for a single variable can be accomplished with a FORMAT and removes the need for adding multiple variables.

 

proc format library=work;
value $filmname
'1'='batman'
'2'='goodwillhunting'
;
run;
data mydata;
input film $ rating;
datalines;
1 2.8
1 3.8
1 4.4
1 2.9
1 2.3
2 2.7
2 3.8
2 3.3
2 4.0
2 4.2
;
run;

proc print data=mydata;
   format film $filmname.;
run;

And you can get different results by using a different format:

proc format library=work;
value $genre
'1'='Comic adventure'
'2'='Drama'
;

proc print data=mydata;
   format film $genre.;
run;

These formats will be honored by most SAS analysis or graphing procedures for creating groups:

proc means data=mydata;
   class film;
   format film $filmname.;
   var rating;
run;

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
How to connect to databases in SAS Viya

Need to connect to databases in SAS Viya? SAS’ David Ghan shows you two methods – via SAS/ACCESS LIBNAME and SAS Data Connector SASLIBS – in this video.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 10 replies
  • 11607 views
  • 6 likes
  • 6 in conversation