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

hello all

I have  the following data set and I'm trying to switch it's value using proc format but it is not working as expected

 

data mysurvay1;
input q1 $ q2 $ q3 $;
DATALINES;
1_strogly_agree 4_not_important 3_very_low
1_strogly_agree 3_somewhat_importatnt 9_left_blank
2_agree 9_left_blank 9_left_blank
4_disagree 2_important normal
9_left_blank 2_important 1_high
agree 3_somewhat_importatnt 2_normal
;
run;
proc format;
invalue $qanswer
"1_high" =1
"1_strogly_agree" =1
"2_agree" =2
"2_important" =2
"2_normal" =2
"3_somewhat_importatnt"=3
"3_very_low" =3
"4_disagree" =4
"4_not_important" =4
"9_left_blank" = .
other =999
;
run;


proc print data=mysurvay1;
format q1-q3 $qanswer.;
run;


expected output

q1 q2 q3
1 4 3
1 3 .
2 . .
4 2 999
. 2 1
999 3 2

 

but what I'm getting is

Abdulla1_0-1668532233799.png

may you help me with that

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

You need to define the INFORMAT before you use it.

If you want the INFORMAT to create a NUMERIC result it needs to be defined as a NUMERIC informat.

 

proc format;
invalue qanswer
  "1_high" =1
  "1_strogly_agree" =1
  "2_agree" =2
  "2_important" =2
  "2_normal" =2
  "3_somewhat_importatnt"=3
  "3_very_low" =3
  "4_disagree" =4
  "4_not_important" =4
  "9_left_blank" = .
  other =999
;
run;

Now that you have the informat defined you can use it to read in text and convert them into numbers. (Just like the 5. informat reads in 5 character digit strings and converts them into numbers).

If you already have the Q1 variables defined as character then make new numeric variables.

data mysurvey1;
  input (q1-q3) (:$50.);
DATALINES;
1_strogly_agree 4_not_important 3_very_low
1_strogly_agree 3_somewhat_importatnt 9_left_blank
2_agree 9_left_blank 9_left_blank
4_disagree 2_important normal
9_left_blank 2_important 1_high
agree 3_somewhat_importatnt 2_normal
;
data want;
  set mysurvey1;
  num1 = input(q1,qanswer.);
  num2 = input(q2,qanswer.);
  num3 = input(q3,qanswer.);
run;

Tom_0-1668536683082.png

 

Or just read them in using the INFORMAT so they are defined as numeric to begin with (you will lose the distinction between the various invalid responses).

data mysurvey1;
  input (q1-q3) (:qanswer.);
DATALINES;
1_strogly_agree 4_not_important 3_very_low
1_strogly_agree 3_somewhat_importatnt 9_left_blank
2_agree 9_left_blank 9_left_blank
4_disagree 2_important normal
9_left_blank 2_important 1_high
agree 3_somewhat_importatnt 2_normal
;

 

View solution in original post

14 REPLIES 14
Abdulla1
Quartz | Level 8

I have just tired to replace invalue with value in the proc format step. yet I'm still getting the same answer.

I also tried to replace the format with informat in the proc print step but now I'm seeing my original data.

is that what you meant?

Tom
Super User Tom
Super User

You need to define the INFORMAT before you use it.

If you want the INFORMAT to create a NUMERIC result it needs to be defined as a NUMERIC informat.

 

proc format;
invalue qanswer
  "1_high" =1
  "1_strogly_agree" =1
  "2_agree" =2
  "2_important" =2
  "2_normal" =2
  "3_somewhat_importatnt"=3
  "3_very_low" =3
  "4_disagree" =4
  "4_not_important" =4
  "9_left_blank" = .
  other =999
;
run;

Now that you have the informat defined you can use it to read in text and convert them into numbers. (Just like the 5. informat reads in 5 character digit strings and converts them into numbers).

If you already have the Q1 variables defined as character then make new numeric variables.

data mysurvey1;
  input (q1-q3) (:$50.);
DATALINES;
1_strogly_agree 4_not_important 3_very_low
1_strogly_agree 3_somewhat_importatnt 9_left_blank
2_agree 9_left_blank 9_left_blank
4_disagree 2_important normal
9_left_blank 2_important 1_high
agree 3_somewhat_importatnt 2_normal
;
data want;
  set mysurvey1;
  num1 = input(q1,qanswer.);
  num2 = input(q2,qanswer.);
  num3 = input(q3,qanswer.);
run;

Tom_0-1668536683082.png

 

Or just read them in using the INFORMAT so they are defined as numeric to begin with (you will lose the distinction between the various invalid responses).

data mysurvey1;
  input (q1-q3) (:qanswer.);
DATALINES;
1_strogly_agree 4_not_important 3_very_low
1_strogly_agree 3_somewhat_importatnt 9_left_blank
2_agree 9_left_blank 9_left_blank
4_disagree 2_important normal
9_left_blank 2_important 1_high
agree 3_somewhat_importatnt 2_normal
;

 

Abdulla1
Quartz | Level 8

Thank you Tom

That is helpful. may you help me on how to read it the data using the informat like on a data that was already defined (has set statement instead of input).

I tired the code

data mysurvey2;
set mysurvey1;
format q1-q3 qanswer.;
run;

Reeza
Super User
data mysurvey2;
set mysurvey1;
array _q(*) q1-q3;
array _new(*) new_q1-new_q3;

do i=1 to dim(_q);
_new(i) = input(substr(_q(i), 1, 1), 8.);
end;

run;

proc print data=mysurvey2;
var new_q1-new_q3;
run;

proc print data=mysurvey1;
var q1-q3;
format q1-q3 $1.;
run;

Try both of the above options.

Abdulla1
Quartz | Level 8

thank you Reeza,

may you explain the $1. below what is that ?

 

proc print data=mysurvey1;
var q1-q3;
format q1-q3 $1.;
run;

 

Reeza
Super User
That's a single character format. Essentially the same idea as take the first character.
Tom
Super User Tom
Super User

@Abdulla1 wrote:

Thank you Tom

That is helpful. may you help me on how to read it the data using the informat like on a data that was already defined (has set statement instead of input).

I tired the code

data mysurvey2;
set mysurvey1;
format q1-q3 qanswer.;
run;


That is something completely different.

INFORMATs are used to convert text into value.  A numeric informat (like in my previous answer) converts text into numbers. A character informat converts text into text (character strings).

FORMATs are used to convert values into text.  A numeric format, like the qanswer format in your code here, converts numbers into text.  A character format converts character string (text) into text.

 

So for this code to work the variables Q1 to Q4 would need to be numeric.  And you would have needed to have define a numeric format that converts values like 1 or 2 into strings. Something like:

proc format ;
value qanswer
  1='1_something_or_other'
  2='2_another_answer'
  ...
  999='Invalid answer'
  .='9_no_response'
;
run;
Abdulla1
Quartz | Level 8

that explains it all.

thank you very much.😀😀😀

Tom
Super User Tom
Super User

This line is defining Q1 to Q4 to each be character with a length of only 8 bytes.

input q1 $ q2 $ q3 $;

If you only read in 8 of the characters then most of the strings will not match the strings in the format(informat?) definition.

4_not_important 

is not the same as

4_not_im
Reeza
Super User
Assuming the spelling mistakes in the code are also in the data?
Abdulla1
Quartz | Level 8

lol they are not in the actual data for sure. but thanks for notifying me.

 

Tom
Super User Tom
Super User

If you want to just convert the first digit into a number then why not just do that?

data test;
  string='4_not_important';
  number = input(string,??1.);
  if number=. then number=999;
  if number=9 then number=.;
run;
Abdulla1
Quartz | Level 8

that is probably the easiest way of doing it, but it will be harder for me to adjusting some of the values, such as "normal" which doesn't have a number before it and I would code it later as 2.

thanks for the suggestion

 

hackathon24-white-horiz.png

2025 SAS Hackathon: There is still time!

Good news: We've extended SAS Hackathon registration until Sept. 12, so you still have time to be part of our biggest event yet – our five-year anniversary!

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 14 replies
  • 2935 views
  • 4 likes
  • 4 in conversation