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

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

1 ACCEPTED SOLUTION

Accepted Solutions
Patrick
Opal | Level 21

Another way of doing it:

%let vars=(var1 var2 var3);
%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;

View solution in original post

9 REPLIES 9
art297
Opal | Level 21

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.

Patrick
Opal | Level 21

Another way of doing it:

%let vars=(var1 var2 var3);
%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;

jbonito
Calcite | Level 5

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

Tom
Super User Tom
Super User

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);

Howles
Quartz | Level 8

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

jbonito
Calcite | Level 5

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

Ksharp
Super User

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

jbonito
Calcite | Level 5

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

Tom
Super User Tom
Super User

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;

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

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
  • 9 replies
  • 3230 views
  • 2 likes
  • 6 in conversation