SAS Select Into Dynamic Naming - select
I am trying to use SAS proc sql select into for 8 different scenarios.
%MACRO Loop();
proc sql;
%do i=1 %to 8;
select total_value
into :Sol_&i. separated by ','
from Master.adjusted_hours
where Solicitation = "&i.";
%end;
quit;
%mend;
%Loop();
However when I use the %put function, the macro variable isn't recognized. The error is "Apparent symbolic reference SOL_1 not resolved."
%put &Sol_1;
How can I store the value in this macro variable and call it later in the code?
You need to declare SOL_1 SOL_2, etc as global macro variables. I wasn't sure what was in your data, so I created some dummy data.
%global SOL_1 SOL_2 SOL_3 SOL_4 SOL_5 SOL_6 SOL_7 SOL_8;
data adjusted_hours;
do x = 1 to 8;
solicitation=put(x, 1.);
do total_value = 1 to 10;
output;
end;
end;
drop x;
run;
%MACRO Loop();
proc sql noprint;
%do i = 1 %to 8;
select total_value
into : Sol_&i. separated by ','
from adjusted_hours
where Solicitation = "&i.";
%end;
quit;
%mend;
%Loop();
%put _USER_;
Partial log:
GLOBAL SOL_1 1,2,3,4,5,6,7,8,9,10
GLOBAL SOL_2 1,2,3,4,5,6,7,8,9,10
GLOBAL SOL_3 1,2,3,4,5,6,7,8,9,10
GLOBAL SOL_4 1,2,3,4,5,6,7,8,9,10
GLOBAL SOL_5 1,2,3,4,5,6,7,8,9,10
GLOBAL SOL_6 1,2,3,4,5,6,7,8,9,10
GLOBAL SOL_7 1,2,3,4,5,6,7,8,9,10
GLOBAL SOL_8 1,2,3,4,5,6,7,8,9,10
If you want to avoid the macro altogether and having to declare the %global variables, here's a data step solution that will work as long as your dataset is sorted by Solicitation.
data _null_;
set adjusted_hours;
by solicitation;
format temp $50.;
retain temp ;
temp=CATX(',',temp, total_value);
if last.solicitation then do;
call symputx(CATS('SOL_', solicitation), temp);
call missing(temp);
end;
run;
Related
loop through multiple rows and output related dataset SAS 9.4
I have a dataset, which is long data. Each subject has 52 week information. The output I want is: data new1 new2 new3 ... new52; set old; if week = 1 then output new1; else if week = 2 then output new2; else....; run;. Since there are 52 weeks,I want to write a macro. Don't know how to...
please see the code below using macro to create 52 datasets.. data old; do week=1 to 52; output; end; run; %macro new(i); data new&i; set old; if week=&i then output; run; %mend new; %macro loop; %do j=1 %to 52; %new(&j); %end; %mend loop; %loop;
SAS distinct level
data test1; input var1$ var2$ ; datalines; 1 a 2 a 3 a 1 b 2 b 1 c ; run; How can I create a macro var that contains all levels of var2? For example: %Let new_var = a b c;
If I understood the question correctly, I think you can try using proc sql for this. proc sql; select distinct var2 into :new_var from test1; quit;
Error in simple SAS macro
I am testing the macro loop. The code is simple but always come the error message "Macro function %SCAN has too many arguments". Could not understand the reason. Anyone could explain it? Thanks! The code is: %macro test; proc sql;select distinct tj, max(tj) into: tp separated by ",", : maxtp from ASA_k where tj>0;quit; %do i=1 %to &maxtp.; %let timep=%scan(&tp.,&i.,","); %put &timep.; %end; %mend; %test;
In macro-varriable, you store values separated by commas, these commas are problematic. You need to mask them after resolving a macro-variable, using %bquote macro-function. Also your third parameter in %scan function is not right, because your separator are , and ". You have to just mask comma using %str macro-function. Just like that: %macro test; proc sql; select distinct tj, max(tj) into :tp separated by ",", :maxtp from ASA_k where tj>0; quit; %do i=1 %to &maxtp.; %let timep=%scan(%bquote(&tp.),&i.,%str(,)); %put &timep.; %end; %mend; %test;
symbolic reference in MACRO IN sas
I have been recieving an error- symbolic reference not resolved when i run the macro in sas using following code: Initially I select as set of Role Numbers using SQL into a list as: PROC SQL NOPRINT; SELECT ROLENO INTO:R1-:R81 FROM ROLLNOS; QUIT; Then a macro is used to select each individual marks and conoslidate them as : options Mprint; %MACRO Marks; %DO I=1 %TO 1; proc sql noprint; create table Marks as select name, rollno, marks, grade from masterdata where rollno= "&R&I."; quit; PROC APPEND DATA=Marks BASE=MarksSheet FORCE;RUN; %END; %MEND; RUN; %Marks; I got an error when the sql statement is executed, Please help me resolve the issue. especially with referencing part- "&R&I."
You want to resolve to R1. &R&I. resolves to macarovariable R (which is not available) and macrovariable I. You need a second & before the R, because 2 & resolve to one. If you use &&R&I, in the first step &&R resolves to &R and &I resolves to 1, so you got &R1. This will then resolve to the macrovariable R1 in second step. Also %do I=1 %to 1 only has one iteration, is this meant to be? options Mprint; %MACRO Marks; %DO I=1 %TO 1; proc sql noprint; create table Marks as select name, rollno, marks, grade from masterdata where rollno= "&&R&I."; quit; PROC APPEND DATA=Marks BASE=MarksSheet FORCE;RUN; %END; %MEND; %Marks;
How to store the distinct values of a variable in macro variable(s)
I have a group macro variable, I would like to make its classes in to macro vars. For example: %macro test(group=); proc freq data=foll; tables &group / out=freqtbl; run; proc sql; create table grp (grpid char(4)); insert into grp values('a') values('b') ; quit; data freqtbl1; merge grp freqtbl; run; data freqtbl2; set freqtbl1; call symput(grpid,&group); run; * &a is the first group, &b is the second group; %mend; This works for 2 classes, but what if it has 3 or more than 3 classes? Thanks a lot.
proc sql; select distinct age into :cls1-:cls10 from sashelp.class; quit; %put &cls1 &cls2 &cls3 &cls4 &cls5 &cls6 &cls7; You'll still have the issue of knowing when to stop when using this (like in the above, &cls7 is not resolved). Set the -:cls10 or whatever to a high enough value you don't run out of variables. If you actually would prefer this to be in one variable, select distinct age into :cls separated by ' ' would make &cls that has all of the values in it. You could also do this in the data step - something like: data _null_; set mydata; by myvar; initialvar=65; if first.myvar then do; call symput(byte(initialvar),myvar); initialvar+1; end; run; This would require you to have it sorted. You could alternately run a similar set of code off of the PROC FREQ result dataset.
This macro will create a macro variable for each distinct observation in a column for a dataset. Var=the column you want a set of macro variables for dataset= the dataset you have the column in %macro var_for_val(dataset=,var=); proc sql noprint; create table dist_var as select distinct &var. from &dataset. ; quit; proc sql noprint; create table dist_Var2 as select monotonic() as id, &var. from dist_var ; quit; proc sql noprint; select distinct max(id) into :max_var from dist_var2 ; quit; %do i = 1 %to &max_var.; %global var_&i.; proc sql noprint; select distinct &var. into :var_&i. from dist_var2 where id = &i. ; quit; %put &&var_&i.; %end; %mend; %var_for_val(sashelp.class,var=age); %put &var_1.;