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

Suppose I have 2 tables - Tables A and B.

 

/*Table A*/
data work.table_a;
input fruits$;
cards;
apple
orange
pear
banana
lemon
;
run;

/* Table B */ data work.table_b; input apple orange banana lemon; cards; 1 2 3 4 2 3 4 5 1 0 2 2 ; run;

Table A consists of just one column with 5 rows containing distinct string values. The number of rows and their values are fixed.

 

Table B consists of columns with names that are a subset of the 5 rows of Table A. In this example, Table B consists of 4 columns and the value "pear" does not belong to this subset. However, this subset may change from time to time. For example, on another occasion when this table is generated, Table B may just have 3 columns, while the values missing from the subset might be "apple" and "banana".

 

I am interested in finding out which are the values that are missing from the subset and subsequently, add them to Table B. The values under these columns will all be zeros.

 

/* Desired Output - column "pear" added to Table B */
data work.desired_output;
input apple orange pear banana lemon;
cards;
1 2 0 3 4
2 3 0 4 5
1 0 0 2 2
;
run;

 

Currently, I am using codes adopted from https://communities.sas.com/t5/SAS-Programming/macro-error-issue/td-p/715467.Specifically, I am typing:

%macro VarExist(ds, var);
%local dsid resx rc;
%let dsid=%sysfunc(open(&ds));
%let resx=%sysfunc(varnum(&dsid, &var));
%let rc=%sysfunc(close(&dsid));
%if &resx>0 %then %do; %put &var exist; %end;
%else %do; data &ds; set &ds; &var=0; run; %end;
%mend;

 

%VarExist(table_b, apple);
%VarExist(table_b, orange);
%VarExist(table_b, pear);
%VarExist(table_b, banana);
%VarExist(table_b, lemon);

 

However, such method may not be the most elegant as the real Table A that I am working on consists of 20+ rows. I would like to enquire if there is a better way to code this? Thank you.

1 ACCEPTED SOLUTION

Accepted Solutions
PGStats
Opal | Level 21

Use a retain statement in a datastep

 

data fruits;
input fruit$;
cards;
apple
orange
pear
banana
lemon
;

data have;
input apple orange banana lemon;
cards;
1 2 3 4
2 3 4 5
1 0 2 2
;

proc sql;
select fruit into :fruits separated by " "
from fruits
quit;

data want;
retain &fruits. (99*0);
set have;
run;
PG

View solution in original post

4 REPLIES 4
PGStats
Opal | Level 21

Use a retain statement in a datastep

 

data fruits;
input fruit$;
cards;
apple
orange
pear
banana
lemon
;

data have;
input apple orange banana lemon;
cards;
1 2 3 4
2 3 4 5
1 0 2 2
;

proc sql;
select fruit into :fruits separated by " "
from fruits
quit;

data want;
retain &fruits. (99*0);
set have;
run;
PG
jlin4
Fluorite | Level 6
thank you! may i ask what does "(99*0)" do?
PGStats
Opal | Level 21

99*0 is the initial values list for the retained variables. The list is too long, but that doesn't matter. Missing variables will thus be created with a value of zero, a value that will never change.

PG
Tom
Super User Tom
Super User

If you want to have a fixed structure then just create that structure.  You could do it with code

data want;
  length apple 8 banana 8 .... ;  
  set have;
run;

or with a dataset

data want;
   set expected(obs=0) have;
run;

If you want to fill the non-existent variables with zeros instead of missing you might want to use RETAIN.  Or if you also want to replace any missing in yoru actual data with zeros then perhaps wait and just replace them all with the same code.

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

Mastering the WHERE Clause in PROC SQL

SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 4 replies
  • 1046 views
  • 5 likes
  • 3 in conversation