BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Q1983
Lapis Lazuli | Level 10

data have;

length Group $50;

input Group $ _NAME_ $ Value date $;

datalines;

 

WWWW AARP 50 1jun2018

TTTT BBRP 123 5may2015

DDDD BBRP 123 5may2015

;

run;

data WWWW TTTT DDDD CCCC;

set have;

if Group = 'WWWW' then output WWWW;

if Group = 'TTTT' then output TTTT;

if Group = 'DDDD' then output DDDD;

if Group = 'CCCC' then output CCCC;/*has no records*/

run;

CCCC will have no records however I want to show the dataset and place a statement under the variable Group and say 'No Records Found'.  Can this be done at the dataset level???

 

1 ACCEPTED SOLUTION

Accepted Solutions
mkeintz
PROC Star

Start out with a single character variable (_NOT_FOUND_LIST) containing a space-separated list of possible group values.  As each group is encountered take it out of the variable.  At the end of the data set write a dummy record for each group value remaining in _not_found_list:

 

data have;
length Group $50;
input Group $ _NAME_ $ Value date $;
datalines;
WWWW AARP 50 1jun2018
TTTT BBRP 123 5may2015
DDDD BBRP 123 5may2015
run; 

data WWWW TTTT DDDD CCCC;
  set have end=end_of_have;
  retain _not_found_list 'WWWW TTTT DDDD CCCC';
  select (group);
    when ('WWWW') output WWWW;
    when ('TTTT') output TTTT;
    when ('DDDD') output DDDD;
    when ('CCCC') output CCCC;  /*has no records*/
  end;
  _not_found_list=tranwrd(_not_found_list,trim(group),'');
  if end_of_have;
  call missing(group,_name_,value,date);
  group='Not found';
  do while (not missing(_not_found_list));
    select (scan(_not_found_list,1));
      when ('WWWW') output WWWW;
      when ('TTTT') output TTTT;
      when ('DDDD') output DDDD;
      when ('CCCC') output CCCC;
    end;
    _not_found_list=tranwrd(_not_found_list,scan(_not_found_list,1),'');
  end;
  drop _not_found_list;
run;

 

One can make it more compact by reducing the number of loops to one, but more carefully managing the loop conditions.

 


data WWWW TTTT DDDD CCCC;
  set have end=end_of_have;
  retain _not_found_list 'WWWW TTTT DDDD CCCC';

  if _not_found_list^=' ' then _not_found_list=tranwrd(_not_found_list,trim(group),'');
  do _n_=1 to 6 until (end_of_have=0  or _not_found_list=' ');
    select (ifc(_n_=1,group,scan(_not_found_list,1)));
      when ('WWWW') output WWWW;
      when ('TTTT') output TTTT;
      when ('DDDD') output DDDD;
      when ('CCCC') output CCCC;  /*has no records*/
    end;
    if _n_=1 then call missing(_name_,value,date);
    if _n_=1 then group='Not Found';
    else _not_found_list=tranwrd(_not_found_list,scan(_not_found_list,1),' ');
  end;
  drop _not_found_list;
run;

 

 

BTW the "do _n_=1 to 6 until ..."  could also be "do _n_=1 by 1 until ...", but the latter risks endless loop unless you know the UNTIL condition will always eventually be met.  So I put "1 to 6", just making sure to choose an upper limit greater than the number of expected groups (4)

--------------------------
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

--------------------------

View solution in original post

5 REPLIES 5
Tom
Super User Tom
Super User

SAS already does that in the LOG.

NOTE: There were 3 observations read from the data set WORK.HAVE.
NOTE: The data set WORK.WWWW has 1 observations and 4 variables.
NOTE: The data set WORK.TTTT has 1 observations and 4 variables.
NOTE: The data set WORK.DDDD has 1 observations and 4 variables.
NOTE: The data set WORK.CCCC has 0 observations and 4 variables.

What are you actually trying to do?

Q1983
Lapis Lazuli | Level 10

In other words for dataset CCCC I would get the dataset with nothing in it.  I want to not only show the dataset CCCC, I want a statement inside the dataset that has the message 'No Records Found'.  I eventually want this to be a single report with 4 tabs.  If no records appear I want the dataset to list the no record statement

Shmuel
Garnet | Level 18

You can put the note 'No Records Found' either in one of your char variables,

assuming it is long enough, or in a new variable which will be absent on the other datasets,

unless you add it to all datasets with any message in it or empty:

data cccc;
 set cccc nobs = m;
      if m=0 then note='No Records Found' ;
      else note = cat('Dataset has ',m, ' records');
run;

You can add counters to your code to to it in same step

data WWWW TTTT DDDD CCCC;
 set have end=eof;
     length note $20;
     retain n1 n2 n3 n4 0  retain note '  ';
     if Group = 'WWWW' then do; n1+1; output WWWW; end; else
     if Group = 'TTTT' then do; n2+1; output TTTT; end; else
     if Group = 'DDDD' then do; n3+1; output DDDD; end; else
     if Group = 'CCCC' then do; n4+1; output CCCC; end;      
     
     array nx n1-n4;
     array dx $ 'WWWW' 'TTTT' 'DDDD' 'CCCC';
     if eof then 
do i=1 to dim(nx); if nx(i) = 0 then do; group = dx(i); note = 'No Records Found'; output; end; end; run;

 

error_prone
Barite | Level 11
Two things to note:
1 splitting data is almost always a bad idea, because more code is required to process the datasets. Search for by-group-processing.
2 a "no records found" statement does not exist. The emptiness of a dataset should be enough. You could add a label to the dataset, but that would require post-processing the dataset.
mkeintz
PROC Star

Start out with a single character variable (_NOT_FOUND_LIST) containing a space-separated list of possible group values.  As each group is encountered take it out of the variable.  At the end of the data set write a dummy record for each group value remaining in _not_found_list:

 

data have;
length Group $50;
input Group $ _NAME_ $ Value date $;
datalines;
WWWW AARP 50 1jun2018
TTTT BBRP 123 5may2015
DDDD BBRP 123 5may2015
run; 

data WWWW TTTT DDDD CCCC;
  set have end=end_of_have;
  retain _not_found_list 'WWWW TTTT DDDD CCCC';
  select (group);
    when ('WWWW') output WWWW;
    when ('TTTT') output TTTT;
    when ('DDDD') output DDDD;
    when ('CCCC') output CCCC;  /*has no records*/
  end;
  _not_found_list=tranwrd(_not_found_list,trim(group),'');
  if end_of_have;
  call missing(group,_name_,value,date);
  group='Not found';
  do while (not missing(_not_found_list));
    select (scan(_not_found_list,1));
      when ('WWWW') output WWWW;
      when ('TTTT') output TTTT;
      when ('DDDD') output DDDD;
      when ('CCCC') output CCCC;
    end;
    _not_found_list=tranwrd(_not_found_list,scan(_not_found_list,1),'');
  end;
  drop _not_found_list;
run;

 

One can make it more compact by reducing the number of loops to one, but more carefully managing the loop conditions.

 


data WWWW TTTT DDDD CCCC;
  set have end=end_of_have;
  retain _not_found_list 'WWWW TTTT DDDD CCCC';

  if _not_found_list^=' ' then _not_found_list=tranwrd(_not_found_list,trim(group),'');
  do _n_=1 to 6 until (end_of_have=0  or _not_found_list=' ');
    select (ifc(_n_=1,group,scan(_not_found_list,1)));
      when ('WWWW') output WWWW;
      when ('TTTT') output TTTT;
      when ('DDDD') output DDDD;
      when ('CCCC') output CCCC;  /*has no records*/
    end;
    if _n_=1 then call missing(_name_,value,date);
    if _n_=1 then group='Not Found';
    else _not_found_list=tranwrd(_not_found_list,scan(_not_found_list,1),' ');
  end;
  drop _not_found_list;
run;

 

 

BTW the "do _n_=1 to 6 until ..."  could also be "do _n_=1 by 1 until ...", but the latter risks endless loop unless you know the UNTIL condition will always eventually be met.  So I put "1 to 6", just making sure to choose an upper limit greater than the number of expected groups (4)

--------------------------
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

--------------------------

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!

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
  • 5 replies
  • 1152 views
  • 3 likes
  • 5 in conversation