For each id count the number of qc=fails, generate a new column final with all values as "repeat" if any one id has 2 or more than 2 fails, else pass. Repeat if count is greater than equal to 2. For some reason the if-else statement does not work. Instead of the final being a repeat for count greater than equal to 2, it is displaying it as pass.dataset
%let repeat_flag = 0;
%let pass_flag = 0;
data _null_;
set exp;
if count ge 2 then call symputx ('repeat_flag',1);
else call symputx ('pass_flag',1);
stop;
run;
%if &repeat_flag %then %do;
data exp;
set exp;
Final = 'REPEAT';
run;
%end;
%if &pass_flag %then %do;
data exp;
set exp;
Final = 'PASS';
run;
%end;
%put &repeat_flag;
%put &pass_flag;
If you want to test if any observation has COUNT larger than one then use a pattern like this instead. Set the macro variable to the FALSE condition and then set it TRUE when the condition is met.
%let pass_flag=PASS;
data _null_;
set exp;
if count ge 2 then do;
call symputx ('pass_flag','REPEAT');
stop;
end;
run;
data want;
set exp;
length final $6;
final="&pass_flag" ;
run;
Related
need help on one query , I have to iterate date in do loop that is in format of yymmd6.(202112) so that once the month reach to 12 then its automatically change to next year first month.
///// code////////
%let startmo=202010 ;
%let endmo= 202102;
%macro test;
%do month= &startmo %to &endmo;
Data ABC_&month;
Set test&month;
X=&month ;
%end;
Run;
%mend;
%test;
//////////
Output should be 5 dataset as
ABC_202010
ABC_202011
ABC_202012
ABC_202101
ABC_20210
I need macro variable month to be resolved 202101 once it reached to 202012
Those are not actual DATE values. Just strings that you have imposed your own interpretation on so that they LOOK like dates to you.
Use date values instead and then it is easy to generate strings in the style you need by using a FORMAt.
%macro test(startmo,endmo);
%local offset month month_string;
%do offset = 0 to %sysfunc(intck(month,&startmo,&endmo));
%let month=%sysfunc(intnx(month,&startmo,&offset));
%let month_string=%sysfunc(putn(&month,yymmn6.));
data ABC_&month_string;
set test&month_string;
X=&month ;
format X monyy7.;
run;
%end;
%mend;
%test(startmo='01OCT2020'd , endmo='01FEB2021'd)
And if you need to convert one of those strings into a date value use an INFORMAT.
%let date=%sysfunc(inputn(202010,yymmn6.));
I would prefer to use a do while loop.
check whether the last 2 characters are 12, if so, change the month part to 01.
code
%let startmo=202010 ;
%let endmo= 202102;
%macro test;
%do %while(&startmo <= &endmo);
Data ABC_&startmo;
Set test&startmo;
X=&startmo ;
Run;
%end;
%let mon = %substr(&startmo, 5, 2);
%let yr = %substr(&startmo, 1, 4);
%if &mon = 12 %then %do;
%let m = 01;
%let startmo = %sysfunc(cat(%eval(&yr + 1), &m));
%end;
%else %do;
%let startmo = %eval(&startmo + 1);
%end;
%mend;
%test;
I have the following code, which stores the number of rows in a table inside the macro-variable n_vars:
data cont_vars;
set var_list;
where flg_categorical = 0;
call symput('n_vars', _n_);
%put &n_vars;
run;
Currently if the resulting table is empty then n_vars resolves to nothing and I want it to be set equal to 0 so I can use it in a %do x = 1 %to &n_vars; loop later.
If the where statement indeed leads to no observation in the dataset, the following code should then set the n_vars macro-variable to 0:
data want;
if eof then call symputx('n_vars',_n_-1);
set have end=eof;
where flg_categorical = 0;
run;
Please consider creating a Minimal Reproducible Example.
data have;
infile datalines delimiter=',';
input x1 flg_categorical;
datalines;
1,1
6,2
3,2
;
run;
data want;
if eof then call symputx('n_vars',_n_-1);
set have end=eof;
where flg_categorical = 0;
run;
%put &=n_vars;
Result:
Anyway I don't know see why you would use a %do loop that would be incremented from 1 to 0.
Maybe you just want to run another kind of steps when the data set is empty. If that is the case, I would consider using:
%if &n_vars. > 0 %then %do; /* data set is not empty */
...
%end;
%else %do; /* data set is empty */
...
%end;
Below is the code to execute a set of data-steps based on the value of the increment variable "i". Since I have assigned the value of i to 1 (numeric and not character value). Ideally the first data-step block need to execute, but in the below case the second data-step block is executing.
%put &i. ; prints 1 in to the log window.
%macro DSN;
%let i = 1 ;
data new_DSN;
run;
%if i = 1 %then %do;
data Dummy ;
run;
data DUMMY_ ;
set DUMMY new_DSN ;
run;
%end;
%else %if i ^= 1 %then %do ;
data DUMMY_ ;
set DUMMY_ new_DSN ;
run;
%end;
%mend DSN;
%DSN;
Your IF statement is not calling &I macro variable, but simply comparing string I to 1. This also explains why your second loop running because technically speaking string "I" is not equal to "1". You just need to put ampersand in front of I in both %IF statements. I also put two %PUT statements to easier see where code is running. See below:
%macro DSN;
%let i = 1 ;
data new_DSN;
run;
%if &i = 1 %then %do;
%PUT First Loop Run;
data Dummy ;
run;
data DUMMY_ ;
set DUMMY new_DSN ;
run;
%end;
%else %if &i ^= 1 %then %do ;
%PUT Second Loop Run;
data DUMMY_ ;
set DUMMY_ new_DSN ;
run;
%end;
%mend DSN;
%DSN;
I have created two global macro variables.
date=10/6/2016
b=simple
I want to create a dataset with variable which refers above macros
below are the variables which i want based on condition.
varible1: Date- which the refers the date macro variable
variable2:condition- if b =simple then condition =y or if b is not equal to simple then condition =n
So dateset will look like below
Date condition
10/6/2016 y
You have two options.
Number one (using macro-variables in a data step):
data result;
format date ddmmyy10.;
date = input("&date", ddmmyy10.);
if "&b" = "simple" then condition = "y";
else condition = "n";
run;
Number two (create macro and generate SAS code based on a macro-variable value):
%macro test;
data result;
format date ddmmyy10.;
date = input("&date", ddmmyy10.);
%if &b = simple %then %do;
condition = "y";
%end;
%else %do;
condition = "n";
%end;
run;
%mend test;
%test
Edited:
Or using PROC SQL:
%let date=12/10/2016;
%let b=simple;
proc sql;
create table result
(
date num format=ddmmyy10.,
condition char(1)
);
quit;
%macro insert;
proc sql;
%if &b = simple %then %do;
%let condition = y;
%end;
%else %do;
%let condition = n;
%end;
insert into result (date, condition) values (%sysfunc(inputn(&date, ddmmyy10.)), "&condition");
quit;
%mend insert;
%insert
The character variable in dataset never matches with the macro variable. The %IF loop never comes true. Kindly advice.
I am trying to match by months and accordingly trying to create array and put counts only for specific months. Not working because the month macro variable never matches with dataset variable having month.
/*create dummy data*/
data datefile;
input tran_date date9. cnt 3.;
datalines;
13feb2015 5
10feb2015 4
11feb2015 3
05feb2015 8
08feb2015 5
01jan2015 1
20dec2014 1
31jan2015 2
23dec2014 2
12jan2015 1
;
/*calculate month*/
data datefile11;
set datefile;
tran_mon=year(tran_date)*100+month(tran_date);
run;
/*select distinct month*/
proc sql;
create table datefile12 as select distinct(tran_mon)
from datefile11 order by tran_mon;
quit;
/*convert month from numeric to character*/
data datefile11(drop=tran_mon);
informat tran_mon2 $6.;
set datefile11;
tran_mon2=tran_mon;
run;
/*create macro variables through datastep*/
data datefile13;
set datefile12;
monum = cat('mnth',_N_);
run;
data _null_;
set datefile13;
call symput(monum,trim(left(tran_mon)));
run;
/*use array to make separate column for each month and
put split count for each month to each colunms*/
%macro c;
proc sql noprint;
select count(1) into :nrow from datefile13;
quit;
%let nrow = &nrow;
data datefile14;
set datefile11;
array mon{*} mon_1 - mon_&nrow;
%do i=1 %to &nrow;
%if tran_mon2 = &&mnth&i %then %do; %put tran_mon2;
mon_&i = cnt; %end;
%else %do; mon_&i = 0 ; %end;
%end;
run;
%mend c;
%c
Your macro %if %then %do check executes while the data step is still being compiled - by the time the data step has begun to execute, there is no further opportunity to use macro logic like that.
Try doing it the other way round - write your loop using if then do data step logic instead.