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

Hello new to SAS, and I am running a macro that loops through the different classes in a variable, in this case, urban, rural, and national.

 

I want to subset each of this data into a temporary table for each pass through to run a paired T-test on each class, however I am having issues with sub setting the data. 

 

(This is just a snapshot of the data, there are also other variables that I want to group by excluded) 

Obs Geography Var1 Var2123
Urban-0.01438-0.12000
Rural-0.08528-0.02000
National-0.03121-0.10000

The code in the macro that does this 

The new dataset that is created is ClassType, which just includes either just all of the "Urban" "Rural" or "National" data

group_var = Geography (In this case) and ClassVar stores the observations of Geography 

 

%MACRO ttest_by_class(ds, group_var, class_vars, numeric_var1, numeric_var2, output);

%LET num_class_vars = %SYSFUNC(COUNTW(&class_vars.));
%DO i = 1 %TO &num_class_vars.;

     %LET ClassVar = %SCAN(&class_vars, &i, ' ');
     DATA ClassType;
         SET &ds.;
         IF(&group_var. = &ClassVar.);
     RUN;

...

 

However, when I run the Data step, the tables that it produces contains are empty, but when I change &ClassVar. to the individual strings "Urban" , it works fine. Is this just not possible with macro variables, or is there a way to convert to string? 

 

Also if there an easier way to do what I am planning on doing, I would like to know. 

1 ACCEPTED SOLUTION

Accepted Solutions
Quentin
Super User

You didn't show your macro call, so it's hard to see the mistake you made.  Definitely it's possible to do that sort of looping and subsetting with a macro.  But since you're new to SAS, and you (sensibly) asked for easier alternative ways, in SAS it is rarely necessary (or even helpful) to split data into subset-specific tables like this.  Instead of looping over data sets, you almost always are better off having one dataset with a grouping variable, and then use that variable in a BY statement for by-group processing.  e.g.:

 

proc sort dat=sashelp.class out=class ;
  by sex ;
run ;

proc ttest data=class ;
  var height ;
  by sex ;
run ;

So that will run a one-sample ttest on sex=F subset, then run it on sex=M.  In order to use BY group processing, your data need to be sorted by the BY variable.

 

The canonical paper on BY group processing is: https://support.sas.com/resources/papers/proceedings/proceedings/forum2007/183-2007.pdf

 

 

 

BASUG is hosting free webinars Next up: Mark Keintz presenting History Carried Forward, Future Carried Back: Mixing Time Series of Differing Frequencies on May 8. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.

View solution in original post

3 REPLIES 3
PaigeMiller
Diamond | Level 26

I want to subset each of this data into a temporary table for each pass through to run a paired T-test on each class, however I am having issues with sub setting the data. 

 

Subsetting the data into separate data sets is usually unnecessary in SAS. Performing paired t-tests on each data set is the wrong approach. Instead, use the BY statement in PROC TTEST. If you do that, no sub-setting is needed, only one data set is needed, and no macro variables are needed, no DO loops are needed.

--
Paige Miller
Quentin
Super User

You didn't show your macro call, so it's hard to see the mistake you made.  Definitely it's possible to do that sort of looping and subsetting with a macro.  But since you're new to SAS, and you (sensibly) asked for easier alternative ways, in SAS it is rarely necessary (or even helpful) to split data into subset-specific tables like this.  Instead of looping over data sets, you almost always are better off having one dataset with a grouping variable, and then use that variable in a BY statement for by-group processing.  e.g.:

 

proc sort dat=sashelp.class out=class ;
  by sex ;
run ;

proc ttest data=class ;
  var height ;
  by sex ;
run ;

So that will run a one-sample ttest on sex=F subset, then run it on sex=M.  In order to use BY group processing, your data need to be sorted by the BY variable.

 

The canonical paper on BY group processing is: https://support.sas.com/resources/papers/proceedings/proceedings/forum2007/183-2007.pdf

 

 

 

BASUG is hosting free webinars Next up: Mark Keintz presenting History Carried Forward, Future Carried Back: Mixing Time Series of Differing Frequencies on May 8. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
Tom
Super User Tom
Super User

What did you put into the macro variable Class_vars?

That will determine what gets put into the macro variable ClassVar .

Which will determine if using it this way:

 IF(&group_var. = &ClassVar.);

Makes any sense.

 

For example if CLASS_VARS = Urban Rural National and GROUP_VAR= Geography then you will end up generating code like:

IF (Geography = Urban) ;

Which is valid SAS syntax that will compare the value of the variable GEOGRAPHY to the value of the variable URBAN.  

But you printout of the data did not have variable named URBAN.

 

So you need to generate code like

IF (Geography = "Urban") ;

instead.

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!

Mastering the WHERE Clause in PROC SQL

SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 3 replies
  • 384 views
  • 0 likes
  • 4 in conversation