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

i have two datasets that created in different years. i want to check to see if all variables in the current year are also in the previous year and vs visa. if not, i will print out the variable name. i find a sas code online to do this work but it only can do one variable at a time. i have 70 variables in each datasets and want to check them all in one time. i am not good on macro so i tried several codes online but can not make them work. 


data year1;
input gender race age;
datalines;
1 1 20
2 4 30
3 5 40
1 7 50
2 9 60
3 5 70
;
run;
data year2;
input gender race age risk;
datalines;
1 1 30 0
1 1 50 1
1 2 60 2
2 3 70 3
2 4 40 4
2 5 40 5
;

run;

this is the code i find online but seems doesn't work for some reason:

%let dsn1=year1;
%let dsn2=year2;
%let dsid=%sysfunc(open(&dsn1,i));
%let nvar1=%sysfunc(attrn(&dsid,nvars));
%do i=1 %to &nvar1;
%let name1=%sysfunc(varname(&dsid,&i));
%let list1=%str( &list1 &name1 );
%end;
%let bad1=&list1;
%let rc=%sysfunc(close(&dsid));

%let dsid=%sysfunc(open(&dsn2,i));
%let nvar2=%sysfunc(attrn(&dsid,nvars));
%let common=;

%do i=1 %to &nvar2;
%let name2=%sysfunc(varname(&dsid,&i));
%let list2=%str( &list2 &name2 );


%let pos_a=
%eval(%index(&bad1,%str( &name2 )));
%let len_var=%length(&name2);
%let pos_b=%eval(&pos_a + &len_var + 1);

%if (&pos_a = 0) %then
%let bad2=%str( &bad2 &name2 );

%else %do;
%let bad1=%str( )
%substr(&bad1,1,&pos_a)%substr(&bad1,&pos_b)
%str( );
%let common=%str( &common &name2 );
%end;

proc sort data=&dsn1(keep=&common);
by &common;
run;

data _prob;
merge &dsn1(in=indsn1) &dsn2(in=indsn2);
by &common;
length inds $ 40;
if indsn1 and not indsn2 then do;
inds="&dsn1";
output;
end;
if not indsn1 and indsn2 then do;
inds="&dsn2";
output;
end;
run;

 

1 ACCEPTED SOLUTION

Accepted Solutions
ballardw
Super User

SAS keeps lots of information available. The data view SASHELP.VCOLUMN has the names and assigned properties of all the variables in all the currently active libraries.

So you can use Sashelp.vcolumn as input to any procedure. Coupled with a Where clause to filter to records you want there are lots of things you can do.

(code corrected to use correct variable name)

proc tabulate data=sashelp.vcolumn;
   where libname='WORK' and member memname in ('YEAR1' 'YEAR2');
   class member memname name type;
   table name*type,
         member memname
   ;
run;

Your example code would by default place the data sets in the WORK library. So the where clause uses that library and Memname is the variable that holds data set or view names. Libname and Memname are both stored in uppercase so you need to use upper case to find them.

The above Proc tabulate will have row for each variable in either data set, row for character or numeric if the variable is both or just the one if it is the same in both (or only data set). There will be a column for each data set. The cells with a 1 indicate where a variable appears. If in both columns then in both sets, or if only one then under that set.

 

I like this Proc Tabulate approach because it works a bit nicer when you need to compare more than two sets at a time. For instance if you omit the Memname part of the Where clause you get all the datasets in a library. Caution: lots of sets with lots of variables may make the output hard to read or possibly exceed working memory.

View solution in original post

4 REPLIES 4
PaigeMiller
Diamond | Level 26

Don't write a macro. Use PROC COMPARE:

 

What Information Does PROC COMPARE Provide?

PROC COMPARE generates the following information about the two data sets that are being compared:

  • whether matching variables have different values
  • whether one data set has more observations than the other
  • what variables the two data sets have in common
  • how many variables are in one data set but not in the other
  • whether matching variables have different formats, labels, or types
  • a comparison of the values of matching observations

 

--
Paige Miller
ballardw
Super User

SAS keeps lots of information available. The data view SASHELP.VCOLUMN has the names and assigned properties of all the variables in all the currently active libraries.

So you can use Sashelp.vcolumn as input to any procedure. Coupled with a Where clause to filter to records you want there are lots of things you can do.

(code corrected to use correct variable name)

proc tabulate data=sashelp.vcolumn;
   where libname='WORK' and member memname in ('YEAR1' 'YEAR2');
   class member memname name type;
   table name*type,
         member memname
   ;
run;

Your example code would by default place the data sets in the WORK library. So the where clause uses that library and Memname is the variable that holds data set or view names. Libname and Memname are both stored in uppercase so you need to use upper case to find them.

The above Proc tabulate will have row for each variable in either data set, row for character or numeric if the variable is both or just the one if it is the same in both (or only data set). There will be a column for each data set. The cells with a 1 indicate where a variable appears. If in both columns then in both sets, or if only one then under that set.

 

I like this Proc Tabulate approach because it works a bit nicer when you need to compare more than two sets at a time. For instance if you omit the Memname part of the Where clause you get all the datasets in a library. Caution: lots of sets with lots of variables may make the output hard to read or possibly exceed working memory.

juliajulia
Obsidian | Level 7
This is exactly what i am looking for. thank you for your help. The 'member' in the original code can not be find, so i changed to 'memname' and it works.
proc tabulate data=sashelp.vcolumn;
where libname='WORK' and member in ('YEAR1' 'YEAR2');
class memname name type;
table name*type,
member
;
run;

ballardw
Super User

@juliajulia wrote:
This is exactly what i am looking for. thank you for your help. The 'member' in the original code can not be find, so i changed to 'memname' and it works.
proc tabulate data=sashelp.vcolumn;
where libname='WORK' and member in ('YEAR1' 'YEAR2');
class memname name type;
table name*type,
member
;
run;


My mistake too late at night.

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!

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
  • 4 replies
  • 2115 views
  • 4 likes
  • 3 in conversation