BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
SASnewbie0
Calcite | Level 5

Hi community! I am not familiar with SAS macro function.

 

I got a dataset like the one below:

SASnewbie0_0-1730864981133.png

I would like to add row (in red).

SASnewbie0_1-1730865068466.png

I have an idea creating records with macro function and looping.

I have created an array for month and table with shop that need generate records.

Array:

_N_      month

1          2023-01

2         2023-02

3         2023-03

Table:

store      cnt

B             2

C             1

 

Any idea on getting a dataset  like the one below?

SASnewbie0_2-1730865871541.png

 

1 ACCEPTED SOLUTION

Accepted Solutions
Patrick
Opal | Level 21

Below approach is performance wise not optimal but it's easy to code and is dynamic.

data have;
  input store $ _dt $ sales;
  format date yymmd7.;
  date=input(catx('-',_dt,'01'),yymmdd10.);
  drop _dt;
datalines;
A 2023-01 100
A 2023-02 50
A 2023-03 120
B 2023-02 110
B 2023-03 90
C 2023-03 80
;
run;

proc sql;
/*  create table want as*/
  select 
    t1.store
    ,t2.date
    ,coalesce(t3.sales,-999) as sales

  from (select distinct store from have) t1 

  full join (select distinct date from have) t2
  on 1

  left join have t3
  on t3.store=t1.store and t3.date=t2.date
  ;
quit;

If you just need to ensure that you've got always the same values for categorical variables when it comes to reporting then eventually do not modify your source table but look into the classdata option available with certain procedures like Proc Means and Proc Tabulate.

And for reporting if you want to print missing values as -999 then look into SAS option missing=...

 

 

View solution in original post

3 REPLIES 3
s_lassen
Meteorite | Level 14

One possibility may be to create a table containing all the store IDs and months that you want, and then merge with the original:

data all;
  set have(keep=store);
  by  store;
  if first.store;
  do month='2023-01','2023-02','2023-03';
    output;
    end;
run;

data want;
  merge have(in=ok) all;
  by store month;
  if not ok then
    sales=-999;
run;
  

I do not think there is any reason to use macros for this.

mkeintz
PROC Star

I agree with @s_lassen 's code showing there is no need for a macro.

 

One minor suggestion that could greatly improve efficiency if the dataset is large.  Generate ALL as a dataset VIEW rather than as a dataset FILE.  This will allow the two passthroughs of HAVE to be synchronized rather than one at a time.

 

{added comment).  As a result there will be no need to write the intermediate dataset ALL to disk, just to immediately reread it.

 

data ALL / view=ALL;
  ...
data WANT;
  ...

 

--------------------------
The hash OUTPUT method will overwrite a SAS data set, but not append. That can be costly. Consider voting for Add a HASH object method which would append a hash object to an existing SAS data set

Would enabling PROC SORT to simultaneously output multiple datasets be useful? Then vote for
Allow PROC SORT to output multiple datasets

--------------------------
Patrick
Opal | Level 21

Below approach is performance wise not optimal but it's easy to code and is dynamic.

data have;
  input store $ _dt $ sales;
  format date yymmd7.;
  date=input(catx('-',_dt,'01'),yymmdd10.);
  drop _dt;
datalines;
A 2023-01 100
A 2023-02 50
A 2023-03 120
B 2023-02 110
B 2023-03 90
C 2023-03 80
;
run;

proc sql;
/*  create table want as*/
  select 
    t1.store
    ,t2.date
    ,coalesce(t3.sales,-999) as sales

  from (select distinct store from have) t1 

  full join (select distinct date from have) t2
  on 1

  left join have t3
  on t3.store=t1.store and t3.date=t2.date
  ;
quit;

If you just need to ensure that you've got always the same values for categorical variables when it comes to reporting then eventually do not modify your source table but look into the classdata option available with certain procedures like Proc Means and Proc Tabulate.

And for reporting if you want to print missing values as -999 then look into SAS option missing=...

 

 

sas-innovate-white.png

Missed SAS Innovate in Orlando?

Catch the best of SAS Innovate 2025 — anytime, anywhere. Stream powerful keynotes, real-world demos, and game-changing insights from the world’s leading data and AI minds.

 

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 3 replies
  • 896 views
  • 4 likes
  • 4 in conversation