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

I would like to subset a dataset if the row matches my condition.

There are n conditions (combination of variable a and b) that resolved correctly in prior steps.  Now, I'm trying to subset the test1 to test2 dataset using the loops (from beginning of the row to final row, j=1 to &final) and if then conditions to create an indicator variable "match".  However, all the "match" variable rows turned out to be zero (0) in test2 dataset, (I do know there are several test1 dataset rows that has the combination I'm seeking to subset.)  Help!

%macro matchdisplay;

    data test2;

    set test1;

        %do j=1 %to &final;

            %do i=1 %to &n;

                %if a=&&var&i and b=&&var&i %then %do; match=1; %end;

                %else %do; match=0; %end;

            %end;

         where match=1;

        %end;

run;

%mend matchdisplay;

%matchdisplay

1 ACCEPTED SOLUTION

Accepted Solutions
ndp
Quartz | Level 8 ndp
Quartz | Level 8

This is will flag match=1 all combinations of group and item found in sample3:

%macro ytd;
proc sql noprint;
select distinct("if group="||quote(strip(group))||" and item="||quote(strip(item))||" then match=1;") into: _condlst separated by " "
from sample3;
quit;

data sample4;
set sample;
match=0;
&_condlst.;
run;
%mend;

%ytd;

View solution in original post

12 REPLIES 12
ballardw
Super User

Did you start with something that worked without any macro variables? You should post that and we might be able to help turn that into a working macro.

This code has several issues that appear to be mixing datastep variables and macro logic which generally are not going to work. If you are attempting to compare the value of a dataset variable A or B then this fails. You would not want a macro %if in that case.

%if a=&&var&i and b=&&var&i %then %do; match=1; %end;

                %else %do; match=0; %end;

And it may help to provide an example data set, preferably as data step code, and what the results should be.

sonicpoem
Fluorite | Level 6

Lost connection to the network just now.  Will provide the data Monday.  Thanks for the prompt response.

sonicpoem
Fluorite | Level 6

Here's an example scenario, data and sample codes (YTD2015):

BRANDITEM         QT
Aapple1
Borange1
Cmelon1
Dapple1
Aapple1
Aapple1
Borange1
Borange1
Dmelon2
Dapple2
Corange2
Bmelon2
Aapple2
Aorange2
Cmelon3
Capple3
Corange3
Dmelon3
Aapple3
Bmelon3

*Viewed 2015 Quarter 1 (Q1) item list to identify the group and item combination that has the threshold of 3 or more ;

data sample1;

    set sample;

    if QT=1;

run;

proc sort data=sample1;by group item;run;

data sample2;

    set sample1;

    by group item;

    if first.item then count=1;

    else count+1;

run;

data sample3;

    set sample2;

    if count ge 3;

run;

*created macro variables for hit combination;

    data _null_;

        set sample3 end=eof;

        call symputx('Groupname'||left(_n_), brand, 'G');

        call symputx('Product'||left(_n_), item, 'G');

        if eof then call symputx('numrows',_n_, 'G');

    run;

%macro popular;

    %do i=1 %to &numrows;

        %put Signal #&i: &&Groupname&i and &&Product&i;

     %end;

%mend;

%popular;

*Gone back to the original YTD2015 list of brands and items to find YTD count of hit combination identified in Q1;

data _null_;

    set sample end=eod;

    if eod then call symputx('all',_n_,'G');

run;

%macro ytd;

    data sample4;

    set sample;

        %do j=1 %to &all;

            %do i=1 %to &numrows;

                %if group=&&Groupname&i and item=&&Product&i %then %do;

                    match=1;

                %end;

                %else %do;

                    match=0;

                %end;

            %end;

        %end;

        if match=1;

run;

%mend ytd;

%ytd  

/*Log showed   "NOTE: The data set WORK.SAMPLE4 has 0 observations and 4 variables."  

ballardw
Super User

Minor bit:

data sample1;

    set sample;

    if QT=1;

run;

proc sort data=sample1;by group item;run;

data sample2;

    set sample1;

    by group item;

    if first.item then count=1;

    else count+1;

run;

data sample3;

    set sample2;

    if count ge 3;

run;

Likely can be replaced with:

proc sort data=sample;by group item; run;

data sample2;

    set sample1 (where=(qt=1));

    by group item;

    if first.item then count=1;

    else count+1;

     if last.item and count ge 3 then output;

run;

I can't tell exactly what you mean by

YTD count of hit combination identified in Q1;

But it sure sounds like something that could generate lots of the combinations from Proc Summary with the right class variables.

sonicpoem
Fluorite | Level 6

Basically, in QT1, you can see that two group and item combinations (A & apple and B & orange) meet my criteria (occurring 3 or more times in the quarter).  Once that is identified, I am looking at the rest of the data (YTD) to subset all the rows that met these two combinations (hopefully tagged with  Match=1).  In the past, I manually subset the YTD by hard-coding the program once the combination(s) of interest was(were) identified.  I was wondering if there's a way to automate this process using macro.

ndp
Quartz | Level 8 ndp
Quartz | Level 8

This is will flag match=1 all combinations of group and item found in sample3:

%macro ytd;
proc sql noprint;
select distinct("if group="||quote(strip(group))||" and item="||quote(strip(item))||" then match=1;") into: _condlst separated by " "
from sample3;
quit;

data sample4;
set sample;
match=0;
&_condlst.;
run;
%mend;

%ytd;

sonicpoem
Fluorite | Level 6

First of all, I apologize for mixing up variable names: group (description and code) and brand (data). They are interchangeable in this scenario.

Second of all, thanks everyone for helping me to troubleshoot this issue.

Finally, thanks to ndp.  Your suggestion worked!    (I marked it "Correct Answer.")

Reeza
Super User

What is the expected outcome based on that input?

sonicpoem
Fluorite | Level 6

The subser of YTD dataset containing all the rows with the combination of group and item identified from the 1st QT.

RickAster
Obsidian | Level 7

Based on the macro logic I don't think this would ever pick out an observation. It all hinges on the macro variable references &Groupname20 and &Product20, which occur in the last iteration of the loop where &i is &numrows. Based on the sample data, these macro variables would never get the values group and item, respectively, so you would always generate the statement match = 0;.

I am not clear on what the actual objective is but if it involves counting occurrences of observations that is hard to do with macro programming and would more easily be done with proc step programming or data step programming.

RickAster
Obsidian | Level 7

This is starting to sound like an inner join. That is, if I understand correctly, the result would be:

proc sql;

create table test2 as

    select a.*

    from sample a inner join sample2 b

    on a.group = b.group and a.item = b.item;

quit;

Maybe I'm missing something but I think this is the general idea.

Tom
Super User Tom
Super User

If we look at your %IF statement we can see why this approach can never work.

%if a=&&var&i and b=&&var&i %then %do; match=1; %end;

%else %do; match=0; %end;

So if I = 1 then &&VAR&I is the value of macro variable VAR1.

Now your IF condition is testing if this macro variable contains a string of characters that is equal to the character string lowercase a AND the character string lowercase b.  It can never be equal to both of those things at the same time.  So you macro code will just generate the data step code:

match=0;

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
  • 12 replies
  • 3181 views
  • 0 likes
  • 6 in conversation