turn on suggestions

Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

Showing results for

Find a Community

- Home
- /
- SAS Programming
- /
- Base SAS Programming
- /
- append text to words in a string

Topic Options

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

03-24-2012 07:14 PM

Hi,

I have string variable which is an input to a macro. It's a variable list that looks like so: (var1 var2 var3). I need to create another string variable that appends text to each of those variable names, for example (var1_mean var2_mean var3_mean). Seems I should be able to make a version of the following work, but not having success with the concatenating:

vars=(var1 var2 var3);

%let meanlist =;

%let items = %sysfunc(countw(&vars));

%do i = 1 %to &items;

%let word = %qscan(&vars,&i,%str( ));

%let meantemp = input ("&word._Mean", 8.1);

%let &meanlist = input ("&meanlist.&meantemp",8.1);

%end;

It's that last %let statement that's not working. SAS says the equals sign is out of order. Thanks in advance for your help.

Joe

Accepted Solutions

Solution

03-24-2012
08:41 PM

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to jbonito

03-24-2012 08:41 PM

Another way of doing it:

%let vars=(var1 var2 var3);

%let meanlist=%sysfunc( prxchange(s/(\w+)/$1_mean/, -1, &vars));

%put meanlist= &meanlist;

%let meanlist=%sysfunc( prxchange(s/(\w+)/$1_mean/, -1, &vars));

%put meanlist= &meanlist;

%let vars=(var1 var2 var3);

%let meanlist=%sysfunc( prxchange(s/(\w+)/$1_mean/, -1, &vars) );

%put meanlist= &meanlist;

All Replies

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to jbonito

03-24-2012 08:15 PM

I can't test it at the moment but, rather than:

%let &meanlist = input ("&meanlist.&meantemp",8.1);

have you tried it with:

%let meanlist = input ("&meanlist.&meantemp",8.1);

???

i.e., leave off the & right after let.

Solution

03-24-2012
08:41 PM

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to jbonito

03-24-2012 08:41 PM

Another way of doing it:

%let vars=(var1 var2 var3);

%let meanlist=%sysfunc( prxchange(s/(\w+)/$1_mean/, -1, &vars));

%put meanlist= &meanlist;

%let meanlist=%sysfunc( prxchange(s/(\w+)/$1_mean/, -1, &vars));

%put meanlist= &meanlist;

%let vars=(var1 var2 var3);

%let meanlist=%sysfunc( prxchange(s/(\w+)/$1_mean/, -1, &vars) );

%put meanlist= &meanlist;

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Patrick

03-24-2012 09:30 PM

Hi Patrick,

That's it! I had no idea SAS supported regular expression matching/searching. Very cool.

And thanks for your reply, Art. I did try that, though to no avail.

Joe

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to jbonito

03-24-2012 10:02 PM

Based on your description of the problem you just need to loop over the words in the string.

Not sure why your list has () around it, but you can add that back at the end.

%let vars=(var1 var2 var3);

%let meanlist =;

%do i = 1 %to %sysfunc(countw(&vars,( )));

%let meanlist=&meanlist %scan(&vars,&i,( ))_mean;

%end;

%let meanlist=(&meanlist);

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to jbonito

03-28-2012 06:01 PM

I don't know what the intended usage is, but if it's to generate suitable variable names in PROC MEANS, the OUTPUT statement's AUTONAME option does this for you.

jbonito wrote:

Hi,

I have string variable which is an input to a macro. It's a variable list that looks like so: (var1 var2 var3). I need to create another string variable that appends text to each of those variable names, for example (var1_mean var2_mean var3_mean). Seems I should be able to make a version of the following work, but not having success with the concatenating:

vars=(var1 var2 var3);

%let meanlist =;

%let items = %sysfunc(countw(&vars));

%do i = 1 %to &items;

%let word = %qscan(&vars,&i,%str( ));

%let meantemp = input ("&word._Mean", 8.1);

%let &meanlist = input ("&meanlist.&meantemp",8.1);

%end;

It's that last %let statement that's not working. SAS says the equals sign is out of order. Thanks in advance for your help.

Joe

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Howles

03-28-2012 06:48 PM

Thanks for your reply. Yes, I know that the Autoname feature does that. What I'm doing is writing a macro that computes some group-level metrics (e.g., coefficient of variance, GINI coefficient), using Proc Means. The user specifies the variables, and the script generates a the list that becomes part of the Proc Means var statement. The computations are done with arrays in a data set, and the array elements need to be generated prior to that step. For example:

%MACRO partner (data=, groupid=, vars=);

%*count the number of variables in the list;

%let items = %sysfunc(countw(&vars));

%*the following creates the array variables in the data steps that follow;

%let meanlist=%sysfunc( prxchange(s/(\w+)/$1_Mean/, -1, &vars) );

%let sdlist=%sysfunc( prxchange(s/(\w+)/$1_StdDev/, -1, &vars) );

%let cvlist=%sysfunc( prxchange(s/(\w+)/$1_CV/, -1, &vars) );

%* Gets group-level estimates;

proc means noprint data=&data;

by &groupid;

var &vars;

output out=sums std(&vars) = mean(&vars) = sum(&vars)= uss(&vars)= /autoname;

run;

%* Computes the relevant statistics at the group level of analysis;

data group_stats;

set sums;

array means(*) &meanlist;

array sds(*) &sdlist;

array cvs(*) &cvlist;

do i = 1 to dim(cvs);

cvs* = sds /means;*

groupsize = _FREQ_;

end;

drop i _TYPE_ _FREQ_;

run;

proc print;

var groupsize &cvlist &meanlist &sdlist;

run;

Works well, or at least well enough for my purposes.

Joe

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to jbonito

03-29-2012 02:16 AM

I don't know why you code it to calculate CV ?

proc means has ability to get it.

proc means data=sashelp.class noprint nway; class sex; var weight; output out=x cv= /autoname;run;

Ksharp

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Ksharp

03-29-2012 05:00 PM

Thanks for your reply. I have other things to calculate, including CV adjusted for group size (Bedeian, 2000), and the Smithson (1982) correction, which is the ratio of observed variation to maximum variation. Easier to keep things in a data step.

Joe

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to jbonito

03-29-2012 06:09 PM

I am not that experienced with /autoname option on the OUTPUT statement.

Wouldn't you insure compatibility with your data step if you used your variable lists to tell PROC MEANS what names to give the calculated statistics?

proc means noprint data=&data;

by &groupid;

var &vars;

output out=sums std=&sdlist mean=&meanlist sum=&sumlist uss=&usslist ;

run;