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

Wondering about methods to hide a row in PROC TABULATE.

 

Suppose I have a simple table with DATE in rows, PASS in column and have a total row.  So daily data for April like:

 

data have ;
  do date='01Apr2024'd to '30Apr2024'd ;
    do id=1 to 5 ;
      pass=ranuni(9)<.3 ;
      output ;
    end ;
  end ;
  format date date9. ;
run ;

proc tabulate data=have;
  class date pass ;
  tables (date all),pass ;
run ;

I want to make that table, but show only the rows for Apr 24 -Apr 30, and the ALL row.  But I want the ALL row to reflect all 30 days, even though the table only shows rows for 7 days.

 

In my mind, I want the table as above, but just hide the rows for Apr 1 - Apr 23.

 

My first thought is to extend my data to have data as is for April 24-30, and then output all the rows again with date set to some arbitrary value that I can use to make an "ALL" row.  So something like:

 

data want ;
  set have ;
  if date>='24Apr2024'd then output ;
  date='09Sep2099'd ;
  output ;
run ;

proc format ;
  value datef
  '09Sep2099'd='01Apr2024 - 30Apr2024'
  other=[date9.]
  ;
run ;

proc tabulate data=want;
  class date pass ;
  tables date,pass ;
  format date datef. ;
run ;

That works and gives me the desired output:

 

 ----------------------------------------------------------
 |                              |          pass           |
 |                              |-------------------------|
 |                              |     0      |     1      |
 |                              |------------+------------|
 |                              |     N      |     N      |
 |------------------------------+------------+------------|
 |date                          |            |            |
 |------------------------------|            |            |
 |24APR2024                     |        3.00|        2.00|
 |------------------------------+------------+------------|
 |25APR2024                     |        3.00|        2.00|
 |------------------------------+------------+------------|
 |26APR2024                     |        4.00|        1.00|
 |------------------------------+------------+------------|
 |27APR2024                     |        3.00|        2.00|
 |------------------------------+------------+------------|
 |28APR2024                     |        5.00|           .|
 |------------------------------+------------+------------|
 |29APR2024                     |        4.00|        1.00|
 |------------------------------+------------+------------|
 |30APR2024                     |        4.00|        1.00|
 |------------------------------+------------+------------|
 |01Apr2024 - 30Apr2024         |      113.00|       37.00|
 ----------------------------------------------------------

But I'm curious about other options.  It almost feels like I could do this with a MULTILABEL format and a CLASSDATA dataset, but in the end I don't think that will work.

 

I will be using ODS for the output (probably ODS POWERPOINT).  So I guess I could try setting a STYLE attribute like ROWHEIGHT=0 for some rows (using CLASSLEV), and see if TABULATE will let me 'hide' a row that way.

BASUG is hosting free webinars Next up: Mark Keintz presenting History Carried Forward, Future Carried Back: Mixing Time Series of Differing Frequencies on May 8. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
1 ACCEPTED SOLUTION

Accepted Solutions
Ksharp
Super User

@Quentin 

 

1)Yes. You can use MULTILABEL option of proc format to get it,but that is too clumsy.Here is an example.

data have ;
  do date='01Apr2024'd to '30Apr2024'd ;
    do id=1 to 5 ;
      pass=ranuni(9)<.3 ;
      output ;
    end ;
  end ;
  format date date9. ;
run ;

proc format ;
  value datef(multilabel notsorted)
  '24Apr2024'd='24Apr2024'
  '25Apr2024'd='25Apr2024'
  '26Apr2024'd='26Apr2024'
  '27Apr2024'd='27Apr2024'
  '28Apr2024'd='28Apr2024'
  '29Apr2024'd='29Apr2024'
  '30Apr2024'd='30Apr2024'
  '01Apr2024'd-'30Apr2024'd='01Apr2024 - 30Apr2024'
  ;
run ;

proc tabulate data=have;
format date datef.;
  class date/mlf preloadfmt order=data;
  class pass ;
  tables date,pass /printmiss;
run ;

Ksharp_0-1714528634655.png

 

 

2) I think the most flexible way is using PROC SQL. If you like it ,I would present it .

View solution in original post

5 REPLIES 5
Quentin
Super User

My thought to use a conditional HEIGHT style on CLASSLEV failed.  Looks like you can use conditional heights, but if you ask for a height that is 0, it gets ignored rather than hiding the row.

 

proc format ;
  value hide
  '01Apr2024'd-'23Apr2024'd='0in'
  other='1in'
  ;
run ;

proc tabulate data=have;
  class date pass;
  classlev date /style={height=hide.};
  tables date*{style=<parent>},pass ;
  format date datef. ;
run ;
BASUG is hosting free webinars Next up: Mark Keintz presenting History Carried Forward, Future Carried Back: Mixing Time Series of Differing Frequencies on May 8. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
Ksharp
Super User

@Quentin 

 

1)Yes. You can use MULTILABEL option of proc format to get it,but that is too clumsy.Here is an example.

data have ;
  do date='01Apr2024'd to '30Apr2024'd ;
    do id=1 to 5 ;
      pass=ranuni(9)<.3 ;
      output ;
    end ;
  end ;
  format date date9. ;
run ;

proc format ;
  value datef(multilabel notsorted)
  '24Apr2024'd='24Apr2024'
  '25Apr2024'd='25Apr2024'
  '26Apr2024'd='26Apr2024'
  '27Apr2024'd='27Apr2024'
  '28Apr2024'd='28Apr2024'
  '29Apr2024'd='29Apr2024'
  '30Apr2024'd='30Apr2024'
  '01Apr2024'd-'30Apr2024'd='01Apr2024 - 30Apr2024'
  ;
run ;

proc tabulate data=have;
format date datef.;
  class date/mlf preloadfmt order=data;
  class pass ;
  tables date,pass /printmiss;
run ;

Ksharp_0-1714528634655.png

 

 

2) I think the most flexible way is using PROC SQL. If you like it ,I would present it .

Quentin
Super User

Thanks @Ksharp !

 

I thought it would be possible with MLF, but I was stuck on the idea of using CLASSDATA to select the rows to display, forgetting that you can do it with preloadfmt order=data.

 

I like the MLF approach, and was planning to use a macro to build the format anyway.

 

If you'd like to show your SQL approach, I'd be happy to see it.  But for my real problem I'll probably stick with TABULATE, since the real table is more complex, with different statistics calculated by TABULATE, trafficlighting, etc.

 

And sorry for not responding sooner. I somehow missed the notification when you responded.  Luckily I got the reminder email today that said "you got responses." 

BASUG is hosting free webinars Next up: Mark Keintz presenting History Carried Forward, Future Carried Back: Mixing Time Series of Differing Frequencies on May 8. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
Ksharp
Super User

Actually I would like to use PROC SQL which is most flexible way to handle REPORT problem, and not need to list all these levels one by one  and could produce any form/style report which PROC TABULATE is unable to do.

data have ;
  do date='01Apr2024'd to '30Apr2024'd ;
    do id=1 to 5 ;
      pass=ranuni(9)<.3 ;
      output ;
    end ;
  end ;
  format date date9. ;
run ;

proc sql;
create table want as
select put(date,date9.) as date,pass,count(*) as count
 from have 
  where date>='24Apr2024'd
   group by date,pass
union all
select 'All',pass,count(*) 
 from have
  group by pass
;
quit;
proc report data=want nowd;
column date pass,count;
define date/group order=data;
define pass/across ;
define count/analysis sum 'N';
run;

Ksharp_0-1714894418340.png

 

Quentin
Super User

Thanks again @Ksharp .  I don't think I've ever used UNION without CORR.  Cool approach.

BASUG is hosting free webinars Next up: Mark Keintz presenting History Carried Forward, Future Carried Back: Mixing Time Series of Differing Frequencies on May 8. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.

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
  • 5 replies
  • 307 views
  • 2 likes
  • 2 in conversation