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

Hi All,

 

I run below code to extract all the numeric columns and name them temp_1, temp_2, temp_3 and so on. But I noticed that it does not output all the columns but the last one only. Beside that, temp_&b. is not working at first iteration, it outputs an error.

 

Can you help solve this? Thanks.

 

The code:

 

data new;

set work.test;

b=1;

array vars _numeric_;

do i=1 to 10;

call symputX('b',b);

temp_&b. = vars[i];

b = symget('b')+1;

call symputX('b',b);

c=i;

end;

run;

1 ACCEPTED SOLUTION

Accepted Solutions
Astounding
PROC Star

 Is there any reason you can't use the original variables instead of "extracting" them to new variables?

 

You seem to be aiming for the first 10 variables only, since your DO loop runs from 1 to 10.  For that, no macro language is needed:

 

data want;

set have;

array vars {*} _numeric_;

array temp_ {10};

do i=1 to 10;

   temp_{i} = vars{i};

end;

run;

 

A few notes about that ...

 

 

If you really want macro variables as we, you can still add a second statement inside the loop:

 

call symputx('temp_' || left(put(i,2.)), vars{i});

 

However such macro variables are probably useless since they get replaced on every observation.

 

Finally, what if you don't know how many numeric variables there are, and you want all of them instead of hard-coding "10"?  One PROC TRANSPOSE solution has been proposed.  While I haven't verified the code, it's definitely a possibility.  Alternatively, you could capture that number as a macro variable and use a two-DATA-step solution:

 

data _null_;

set have;

array vars {*} _numeric_;

call symputx('n_nums', dim(vars));

stop;

run;

 

Then &N_NUMS is the number of numeric variables, and you can plug that into the second DATA step in both places that "10" now appears.

View solution in original post

4 REPLIES 4
Tom
Super User Tom
Super User

When the data step is compiled the macro references, like &B, are resolved before the step starts to run. So the value of a macro varaible generated during a data step cannot be used to generate any of the SAS code for the step that is currently running.  

 

So if you run this code you will create a variable name FRED and not one named SAM.

%let name=FRED;
data want;
  call symputx('name','SAM');
  &name = 10;
run;

What are you actually trying to do with that program?  Please post example input and output data.

Quentin
Super User

If you code (in a new session):

 

data _null_;
  b=1;
  call symputX('b',b);
  temp_&b=2;
run;

It will not work:

 

45   data _null_;
46     b=1;
47     call symputX('b',b);
48     temp_&b=2;
       -----
       180
WARNING: Apparent symbolic reference B not resolved.
ERROR 180-322: Statement is not valid or it is used out of proper order.

49   run;

 

It will not work because when the data step  is being compiled, the the macro processor sees the reference to the macro variable b and tries to resolve it.  But there is no macro variable named b yet, because the CALL SYMPUTX statement has not executed yet.  This is why the general rule is you cannot use CALL SYMPUTX to create a macro variable and refer to the macro variable in the same step.  The timing doesn't work out because the macro variable reference is resolved (or attempted to resolve) before CALL SYMPUTX has executed.

 

SYMGET allows you to look up the value of a macro variable during data step execution time.  Which is why the following will work:

55   data _null_;
56     b=1;
57     call symputX('b',b);
58     b = symget('b')+1;
59     put b=;
60   run;

NOTE: Character values have been converted to numeric values at the places given by:
      (Line):(Column).
      58:7
b=2

 

Can you say more about your big picture goal?  Is it that you want to rename the variables, or do you want an array of temporary variables, or something else?

BASUG is hosting free webinars Next up: Mike Sale presenting Data Warehousing with SAS April 10 at noon ET. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
RW9
Diamond | Level 26 RW9
Diamond | Level 26

I agree with @Quentin, providing more context would allow better answers.  For instance another method would be to normalise the data, i.e. transpose all the numeric variables down, change to whatever you need then transpose again, avoiding loops and such like, for ex:

proc transpose data=have out=inter;
  by <idvars here>;
  var _numeric_;
run;

data inter;
  set inter;
  /* code to change _name_ to whatever you need */
run;

proc transpose data=interout=want;
  by <idvars here>;
  var ...;
id _name_; run;
Astounding
PROC Star

 Is there any reason you can't use the original variables instead of "extracting" them to new variables?

 

You seem to be aiming for the first 10 variables only, since your DO loop runs from 1 to 10.  For that, no macro language is needed:

 

data want;

set have;

array vars {*} _numeric_;

array temp_ {10};

do i=1 to 10;

   temp_{i} = vars{i};

end;

run;

 

A few notes about that ...

 

 

If you really want macro variables as we, you can still add a second statement inside the loop:

 

call symputx('temp_' || left(put(i,2.)), vars{i});

 

However such macro variables are probably useless since they get replaced on every observation.

 

Finally, what if you don't know how many numeric variables there are, and you want all of them instead of hard-coding "10"?  One PROC TRANSPOSE solution has been proposed.  While I haven't verified the code, it's definitely a possibility.  Alternatively, you could capture that number as a macro variable and use a two-DATA-step solution:

 

data _null_;

set have;

array vars {*} _numeric_;

call symputx('n_nums', dim(vars));

stop;

run;

 

Then &N_NUMS is the number of numeric variables, and you can plug that into the second DATA step in both places that "10" now appears.

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

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
  • 1529 views
  • 2 likes
  • 5 in conversation