I am trying to get both FORMA and FORMB in my output. But every time I try to run the code below it just prints out FORMB. What is the proper steps to get both outputs for FORMA and FORMB without writing more code and using the Macros I created? Thanks.
%LET A = A;
%LET A = B;
PROC IMPORT OUT=Form&A DATAFILE="/home/brandonbayles881/EPG194/Form&A..csv"
DBMS=csv REPLACE;
GETNAMES=YES;
RUN;
PROC IMPORT OUT=Domains_Form&A
DATAFILE="/home/brandonbayles881/EPG194/Domains Form&A..csv" DBMS=csv
REPLACE;
GETNAMES=YES;
RUN;
%macro runimport(A=) ;
PROC IMPORT OUT=Form&A DATAFILE="/home/brandonbayles881/EPG194/Form&A..csv"
DBMS=csv REPLACE;
GETNAMES=YES;
RUN;
PROC IMPORT OUT=Domains_Form&A
DATAFILE="/home/brandonbayles881/EPG194/Domains Form&A..csv" DBMS=csv
REPLACE;
GETNAMES=YES;
RUN;
%mend runimport;
%runimport(A=A);
%runimport(A=B);
Because every time you run these two PROC IMPORT steps, macro variable &A has value B. Macro variable &A doesn't have value A by the time your run PROC IMPORT.
%LET A = A;
PROC IMPORT OUT=Form&A DATAFILE="/home/brandonbayles881/EPG194/Form&A..csv"
DBMS=csv REPLACE;
GETNAMES=YES;
RUN;
%LET A = B;
PROC IMPORT OUT=Domains_Form&A
DATAFILE="/home/brandonbayles881/EPG194/Domains Form&A..csv" DBMS=csv
REPLACE;
GETNAMES=YES;
RUN;
Thanks. That makes sense. How would you fix this then so it runs both forms?
Or should I run one and then the other? Would that give me both outputs? If I have just one Macro statement and change the variable to B for example after I run it for A?
I just added the fix to my reply above.
Also, as a matter of terminology, you might want to note that you are not using a macro. There are no macros in your example. You are using a macro variable, which is different than a macro.
%LET A = A;
PROC IMPORT OUT=Form&A DATAFILE="/home/brandonbayles881/EPG194/Form&A..csv"
DBMS=csv REPLACE;
GETNAMES=YES;
RUN;
%LET A = B;
PROC IMPORT OUT=Domains_Form&A
DATAFILE="/home/brandonbayles881/EPG194/Domains Form&A..csv" DBMS=csv
REPLACE;
GETNAMES=YES;
RUN;
Thank you for the tip. Sorry, I don't think I was super clear in my description above. So in the code above, I am trying to import 4 data sets not just two separate ones. Overall when all is said and done I would like to have FORMA, FORMB, Domains_FormA, and Domains_FormB. Using what was suggested gives me Domains_FormB and FORMA as my output.
Why do you need a macro variable for this anyway? This has only complicated the matter.
I suppose you might say that this is a learning exercise, but macro variables simply aren't appropriate or needed here, that's the learning you need to have in this situation..
I suppose you might say that this is a very simplified example of a much more complicated process, in which case macro variables might be useful. Okay, fine, I can understand that, and the first step in making code work on a small portion of the problem is to get it to work WITHOUT macro variables; and then replace the non-macro-variable code with code that has macro variables. So start there ... show us working code without macro variables.
You are correct this was just the begging part of my code. Below is my working code. And this is a learning exercise. This code does work without the macro variables. Once I get to the proc SQL step below and every step after is where I would need all the following tables I described. The steps proceeding my proc SQL code also work I just had to copy the beginning part of my code and run it again for the other form. I Which almost doubled my code and made it really long. I would like to try and avoid what I am doing in the picture above my code.
/* Import Data */
/* Questions 1-2 */
%LET A = A;
%LET A = B;
PROC IMPORT OUT=Form&A DATAFILE="/home/brandonbayles881/EPG194/Form&A..csv"
DBMS=csv REPLACE;
GETNAMES=YES;
RUN;
PROC IMPORT OUT=Domains_Form&A
DATAFILE="/home/brandonbayles881/EPG194/Domains Form&A..csv" DBMS=csv
REPLACE;
GETNAMES=YES;
RUN;
DATA Results&A;
SET Form&A;
Form="Form &A";
ARRAY Form&A(*) Q1-Q150 _CHARACTER_;
ARRAY key(*) K1-K150 _CHARACTER_;
ARRAY match(*) M1-M150 _NUMERIC_;
RETAIN K1-K150;
IF Student="KEY" THEN
DO i=1 to 150;
key(i)=Form&A(i);
END;
ELSE
DO QuestionNum=1 to 150;
IF key(QuestionNum)=Form&A(QuestionNum) THEN
match(QuestionNum)=1;
ELSE
match(QuestionNum)=0;
Scores=match(QuestionNum);
OUTPUT;
END;
KEEP Student QuestionNum Scores Form;
RUN;
PROC PRINT NOOBS DATA=Results&A;
RUN;
TITLE "FINAL FORM";
PROC SQL;
CREATE TABLE FINAL_FORM_&A AS SELECT Student, Results&A..QuestionNum, Scores,
DomainNum, Form FROM Results&A INNER JOIN Domains_Form&A
ON Results&A..QuestionNum=Domains_Form&A..QuestionNum;
QUIT;
PROC PRINT DATA=FINAL_FORM_&A;
RUN;
PROC SQL;
CREATE TABLE COMBINED AS SELECT* FROM FINAL_FORM_A UNION ALL SELECT * FROM
FINAL_FORM_B;
Format Student 9.;
QUIT;
PROC PRINT DATA=COMBINED;
RUN;
PROC MEANS DATA=COMBINED MEAN SUM NONOBS;
VAR Scores;
CLASS Student DomainNum;
ID Form;
OUTPUT OUT=COMBINED_TABLE (DROP=_TYPE_ _FREQ_) SUM=score
MEAN=Student_Percentage;
RUN;
So SAS has methods to read all CSV files at once from a common folder.
You could read all into a single file - with a new variable indicating the source of the file.
Then you could add GROUP by processing which handles each group the same but treats groups independent, similar to separate data sets.
Or you can create a macro and loop the full program every time. If you do this, make sure to add a step at teh end that deletes all temporary data sets so that you don't carry over errors.
Here's a short post on reading all files at once:
This is a better approach because PROC IMPORT guesses and not always correctly. So what may end up happening as you run this for different files, is that you'll end up with a file that has the same variables but different types (character/numeric) and it will cause errors in your code. So if you need to read the file with the same structure multiple times, it's best to not use PROC IMPORT at all. In the long run, this method will save you time, since you won't be dealing with type issues.
And here's one on turning a working program into a macro:
https://github.com/statgeek/SAS-Tutorials/blob/master/Turning%20a%20program%20into%20a%20macro.md
%macro runimport(A=) ;
PROC IMPORT OUT=Form&A DATAFILE="/home/brandonbayles881/EPG194/Form&A..csv"
DBMS=csv REPLACE;
GETNAMES=YES;
RUN;
PROC IMPORT OUT=Domains_Form&A
DATAFILE="/home/brandonbayles881/EPG194/Domains Form&A..csv" DBMS=csv
REPLACE;
GETNAMES=YES;
RUN;
%mend runimport;
%runimport(A=A);
%runimport(A=B);
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 16. Read more here about why you should contribute and what is in it for you!
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.
Select SAS Training centers are offering in-person courses. View upcoming courses for: