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

Hi sas experts,  I have a dataset 

data example;

input var1 var2 var3;cards;

01 MAP 0 

01 MAP 1

01 CVP 0

01 CVP 1

01 CVP 2

01 GCS 0

01 GCS 1

01 HR 0

01 HR 1

02 MAP 0

02 MAP 1

02 MAP 2

02 MAP 3

02 CVP 0

02 CVP 1

02 CVP 2

02 CVP 3

02 GCS 0 

02 GCS 1

02 HR 0

02 HR 1

02 HR 2 

03 MAP 0

03 MAP 1

03 CVP 0

03 GCS 0

;run;

in the dataset i have numerical ordering variable (var3) for by each var1 var2, its a sorted dataset. I want to create a new variable where i can assign values such as:  form 01 to last category obs of var1(084 in my actual dataset), any no of times MAP appears in the observation the newvar= would be 1 and similarly CVP=2, GCS=3, HR=4.

please suggest how to solve this using do loop. Also it would be really helpful if any expert could guide for adding a counter in loop for the below code, as it works only for 01 and MAP and for other observations it simply takes the row number.

data nDATA;
set example;
retain newvar;
by var1 var2;
if first.var2 then newvar=_n_;
output;
run;

1 ACCEPTED SOLUTION

Accepted Solutions
Kurt_Bremser
Super User

First of all, software testing is a virtue and not a crime. It is not forbidden by any country's constitution that I know of.

Therefore you MUST(!!!) test code that you post for example data. Had you done this, it would have revealed that one cannot read values like MAP into a numeric variable.

With slightly corrected example data code (note the $ to read var2 as character), my works as intended:

data example;
input var1 var2 $ var3;
cards;
01 MAP 0 
01 MAP 1
01 CVP 0
01 CVP 1
01 CVP 2
01 GCS 0
01 GCS 1
01 HR 0
01 HR 1
02 MAP 0
02 MAP 1
02 MAP 2
02 MAP 3
02 CVP 0
02 CVP 1
02 CVP 2
02 CVP 3
02 GCS 0 
02 GCS 1
02 HR 0
02 HR 1
02 HR 2 
03 MAP 0
03 MAP 1
03 CVP 0
03 GCS 0
;

data nDATA;
set example;
retain newvar;
by var1 var2 notsorted;
if first.var2
then if var2 = 'MAP'
  then newvar = 1;
  else newvar + 1;
run;

proc print data=ndata noobs;
run;

Result:

var1	var2	var3	newvar
1	MAP	0	1
1	MAP	1	1
1	CVP	0	2
1	CVP	1	2
1	CVP	2	2
1	GCS	0	3
1	GCS	1	3
1	HR	0	4
1	HR	1	4
2	MAP	0	1
2	MAP	1	1
2	MAP	2	1
2	MAP	3	1
2	CVP	0	2
2	CVP	1	2
2	CVP	2	2
2	CVP	3	2
2	GCS	0	3
2	GCS	1	3
2	HR	0	4
2	HR	1	4
2	HR	2	4
3	MAP	0	1
3	MAP	1	1
3	CVP	0	2
3	GCS	0	3

View solution in original post

4 REPLIES 4
Kurt_Bremser
Super User

There is no reason for a do loop, as the data step already is a loop when reading a dataset (or an external file).

_n_ is an automatic variable that is set to the number of the current data step iteration at the beginning of the iteration.

What you need is a retained variable that is set when var2 changes:

data nDATA;
set example;
retain newvar;
by var1 var2 notsorted;
if first.var2
then if var2 = 'MAP'
  then newvar = 1;
  else newvar + 1;
run;

Note that the data step executes an implicit output at the end of each iteration if no explicit output statement is present.

Because an increment statement is used, you could omit the retain statement; variables incremented in this way are automatically retained.

sahoositaram555
Pyrite | Level 9
Hi @Kurt_Bremser, Thanks for your help.Sorry to say but, newvar is retaining only 1 through out entire observations. Also below statement from your code , i'm curious to know can we use two if statements like that ? Please help me know.
if first.var2
then if var2 = 'MAP'
Kurt_Bremser
Super User

First of all, software testing is a virtue and not a crime. It is not forbidden by any country's constitution that I know of.

Therefore you MUST(!!!) test code that you post for example data. Had you done this, it would have revealed that one cannot read values like MAP into a numeric variable.

With slightly corrected example data code (note the $ to read var2 as character), my works as intended:

data example;
input var1 var2 $ var3;
cards;
01 MAP 0 
01 MAP 1
01 CVP 0
01 CVP 1
01 CVP 2
01 GCS 0
01 GCS 1
01 HR 0
01 HR 1
02 MAP 0
02 MAP 1
02 MAP 2
02 MAP 3
02 CVP 0
02 CVP 1
02 CVP 2
02 CVP 3
02 GCS 0 
02 GCS 1
02 HR 0
02 HR 1
02 HR 2 
03 MAP 0
03 MAP 1
03 CVP 0
03 GCS 0
;

data nDATA;
set example;
retain newvar;
by var1 var2 notsorted;
if first.var2
then if var2 = 'MAP'
  then newvar = 1;
  else newvar + 1;
run;

proc print data=ndata noobs;
run;

Result:

var1	var2	var3	newvar
1	MAP	0	1
1	MAP	1	1
1	CVP	0	2
1	CVP	1	2
1	CVP	2	2
1	GCS	0	3
1	GCS	1	3
1	HR	0	4
1	HR	1	4
2	MAP	0	1
2	MAP	1	1
2	MAP	2	1
2	MAP	3	1
2	CVP	0	2
2	CVP	1	2
2	CVP	2	2
2	CVP	3	2
2	GCS	0	3
2	GCS	1	3
2	HR	0	4
2	HR	1	4
2	HR	2	4
3	MAP	0	1
3	MAP	1	1
3	CVP	0	2
3	GCS	0	3
sahoositaram555
Pyrite | Level 9
Thank you very much @Kurt_Bremser, Noted your points. I agree.

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
  • 4 replies
  • 404 views
  • 1 like
  • 2 in conversation