PDA

View Full Version : Something similar to "paste" in R in SAS?



Ruser
06-05-2010, 01:43 AM
Hi everybody!

I'm coming from R but am (unfortunaltely) forced to use SAS at the moment. So this might be some kind of beginner question :rolleyes:.
I'm desperately looking for a similar function in SAS to the "paste" command in R.

To give you an idea:

I have 5 variables called V1a, V2a, V3a, V4a, and V5a in a data frame df, which are multiplied by some number n and asigned to 5 new variables V1b to V5b in the same data frame.
In R I would write a loop:

for i (1 to 5 ){

df[[ paste("V", i, "b", sep="" )]] <- df[[ paste( "V", i, "a", sep ="")]] * n

}

I have searched the SAS help and the net but found nothing similar to this in SAS. Does anyone know the tric, I can't imagine that it should not be possible to do this in SAS?

Thank you for reading. :wave:
Best!

Dason
06-05-2010, 01:14 PM
The general concept that paste does is called "string concatenation" so searching for that might help. The following two pages might help:

This one gives some code but isn't how I would do it (http://www.ats.ucla.edu/stat/sas/code/catx.htm)

Here you'd want to search for "string concatenation" (http://www.ats.ucla.edu/stat/sas/library/SASTranMan_os.html)

Hope this helps.

Ruser
06-05-2010, 01:46 PM
Thank you very much, now I learned something new :)

Unfortulately this is not precisely what I'm looking for, my fault the question was ill posed. In both of your examples the modification is on data entries while I want to modify variable names. If I apply || || on a variable name I get an error:
"statement is not valid or is used out of proper order".
I have a huge amount of variable names that increase by one number in some or other way, fx. V99100, V99101, V99102, ..., or V99100, V99200, V99300,.... I have to do repeating operations on the variables and it would shorten the script (and the typing ) if I could just apply a do loop, like in the example.
So instead of writing

data test;
set test1;
V99101 = V99101 * n;
V99102 = V99102 * n;
....
run;

it would be much smarter to write

data test;
set test1;
do i=1 to m;
"V9910"+i = "V9910"+i * n;
end;
run;

Hm, can't be so hard after all. :)

Mean Joe
06-05-2010, 03:43 PM
One way to do this is a macro. In SAS, macros are "code pasters".

*Define a macro: multiply a specific variable by a specific number*;
&#37;macro vn_mult;
%let i=1;
%do %while (&i<=9);
V9910&i = V9910&i * 100;
%let i = %eval(&i+1);
%end;
%mend vn_mult;

*Now you can call the macro (within a data step);
data test;
set test1;
%vn_mult;
run;


Note that this macro is limited: it only works for a variable with a specific name V9910i, and only multiplies by a specific number 100.

You can make it more general: when SAS parses the macro definition, when it gets to an &, it will replace the following string with the previously-referenced value for the string.

*More general macro, this one uses parameters in the definition;
%macro vn_mult_gen(varname, multiplier);
%let i=1;
%do %while (&i<=9);
&varname.&i = &varname.&i * &multiplier;
%let i = %eval(&i+1);
%end;
%mend vn_mult_gen;

data test;
set test1;
%vn_mult_gen(V9910, 100);
*This macro will multiply all variables V99101 thru V99109 by 100;
%vn_mult_gen(Va, 246);
*This macro will multiply all variables Va1 thru Va9 by 246;
run;

Mean Joe
06-05-2010, 03:48 PM
Where R would say paste("V9910", i, sep="" ),
SAS says V9910.&i

The . tells SAS where to sep the base name from the suffix name. You can make multiple seps in SAS

eg V.&i.b would give you V1b thru V9b

Ruser
06-06-2010, 05:51 AM
Thank you very much, you solved my problem, works fine now.

Here is a nice link concerning the subject:

http://www.stat.ubc.ca/~webmaste/howto/statsoftware/sasmacro.html#combinetext

Ruser
06-09-2010, 02:17 AM
Hi again

now I'm coming with the next stupid question.

What if 'i' has breaks, fx. i = 1,3,4,5,8
Outside of macro world I would write:

do i = 1 3 4 5 8;
<code>
end;

But that doesn't work in the macro language.
I solved it so far by using an if-condition
but I like the other solution much better. Can anybody help (again)?

Thanks!