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

As I recently posted here, I'm trying to create Table 1 for a research journal article. @Reeza pointed me to the Table 1 macro "TableN" and it looks like exactly what I need.

 

I downloaded the macro and ran it, and then I tried to call it based on the example provided.

 

/*Example macro call*/
/*%tablen(data=example, by=arm, 
     var=age date_on sex race1 smoke_st num_met,
     type=1 3 2, outdoc=~/ibm/example1.rtf);*/

/*My version*/
%tablen(data=have, by=TM_group, 
     var=DEM_AGE DEM_SEX,
     type=2 2, outdoc="C:\data_output\test.rtf);

But I got an error after "by TM_group": ERROR: All positional parameters must precede keyword parameters. I looked up the error and it has something to do with the commas between the parameters. After some trial and error of deleting commas, I got it to run without error, but it doesn't produce any output.

 

 

Sample data is provided below:

data have;
  infile datalines dsd dlm=',' truncover;
  input DEM_AGE DEM_SEX cohort_flag TM_group;
datalines;
3,1,1,0
2,1,1,1
3,2,1,1
3,2,1,1
3,2,1,0
2,2,1,1
2,1,1,1
3,1,1,1
2,1,1,1
3,2,1,0
2,1,1,0
2,2,1,1
3,2,1,0
2,2,0,
3,2,1,1
3,2,1,1
3,1,1,0
3,2,1,0
2,1,1,0
3,1,1,1
3,2,1,1
3,2,1,0
3,2,1,1
3,2,1,1
3,2,1,1
; RUN;

proc format library=temp;

value age2grp
1='1:Age Group <65'
2='2:Age Group [65,75)'
3='3:Age Group >=75'
.='Inapplicable/Missing';

value sex
.='Inapplicable/Missing'
1='1:Male'
2='2:Female'
value yesfmt
1='1:Yes'
2='2:No'
.='Inapplicable/Missing'
;
RUN;


 

1 ACCEPTED SOLUTION

Accepted Solutions
Wolverine
Quartz | Level 8

This works! It worked with the sample data, so I removed the datalines and added my real data to the data step and that works too! 😁

 

However, I need to restrict to certain cases in the file. Previously, I used "Where cohort_flag = 1;", but I don't know where to put that in this code.

View solution in original post

17 REPLIES 17
Patrick
Opal | Level 21
The value (path) passed to parameter outdoc has unbalanced quotes.
I assume you shouldn’t use any quotes at all.
ballardw
Super User

The sort of errors caused by unbalanced quotes passed as macro parameters likely means that your SAS session may have issues with getting things to execute. May want to save the code (with corrections for quotes, i.e. none) and then restart your SAS session.

 

 

 

 

Wolverine
Quartz | Level 8

I closed the SAS session, opened a new SAS session, reran the macro, and then tried the macro call without quotes for the outdoc. I also tried making sure the quotes were balanced. In both cases, there were no errors but also no output.

ballardw
Super User

What did the LOG show?

 

Did you compile the macro in the session prior to the call? You have to execute the code with the macro definition if you do not place the macro code file in a place SAS looks for macros (autocall library).

Wolverine
Quartz | Level 8

When I opened the new SAS session, the first thing I did was rerun the macro syntax. I reviewed the log and there were no errors. However, now that I'm taking a closer look at it, I also notice there are no notes or warnings either. In effect, the log simply shows all the syntax that was submitted. Could that indicate that the macro didn't actually compile for some reason?

 

As a check, I opened a 2nd SAS session and ran just the macro call. As expected, it gave me a warning that "macro TABLEN not resolved".

 

When I run the call after the macro has already been run, the log simply shows the macro call, without any errors, notes, or warnings.

 

It seems like the SAS knows that the macro is there, so I can call it without a warning or error. But the macro itself isn't actually executing for some reason.

 

ballardw
Super User

You should get something in the log indicating compilation such as:

60   %macro dummy();
61      proc print data=sashelp.class;
62      run;
63   %mend;
NOTE: The macro DUMMY completed compilation without errors.
      5 instructions 92 bytes.

Which version did you download and use?

When I compile the version in tablen_05102022.sas I get:

NOTE: The macro TABLEN completed compilation without errors.
      7334 instructions 258444 bytes.
Wolverine
Quartz | Level 8

@ballardw wrote:

You should get something in the log indicating compilation such as:

60   %macro dummy();
61      proc print data=sashelp.class;
62      run;
63   %mend;
NOTE: The macro DUMMY completed compilation without errors.
      5 instructions 92 bytes.

Which version did you download and use?

When I compile the version in tablen_05102022.sas I get:

NOTE: The macro TABLEN completed compilation without errors.
      7334 instructions 258444 bytes.

I'm also using tablen_05102022.sas, but I am definitely not getting those notes in the log.

ballardw
Super User

@Wolverine wrote:

@ballardw wrote:

You should get something in the log indicating compilation such as:

60   %macro dummy();
61      proc print data=sashelp.class;
62      run;
63   %mend;
NOTE: The macro DUMMY completed compilation without errors.
      5 instructions 92 bytes.

Which version did you download and use?

When I compile the version in tablen_05102022.sas I get:

NOTE: The macro TABLEN completed compilation without errors.
      7334 instructions 258444 bytes.

I'm also using tablen_05102022.sas, but I am definitely not getting those notes in the log.


What size is your tablen_05102022.sas file? Is the last line in file %mend; ?

I wonder if you may have had a hiccup when downloading the file and have an incomplete version.

Reeza
Super User

This worked for me. 

 

filename tableN url 
 'https://gist.githubusercontent.com/statgeek/b55d964c99975c2ba23fa771afe616bc/raw/b30d55caf6ec4028f5afed3b260ce86b50419ddb/tablen.sas';

%include tableN;

proc format;

value age2grp
1='1:Age Group <65'
2='2:Age Group [65,75)'
3='3:Age Group >=75'
.='Inapplicable/Missing';

value sex
.='Inapplicable/Missing'
1='1:Male'
2='2:Female';

value yesfmt
1='1:Yes'
2='2:No'
.='Inapplicable/Missing'
;
RUN;

data have;
  infile datalines dsd dlm=',' truncover;
  input DEM_AGE DEM_SEX cohort_flag TM_group;
  format dem_age age2grp. dem_sex sex.;
datalines;
3,1,1,0
2,1,1,1
3,2,1,1
3,2,1,1
3,2,1,0
2,2,1,1
2,1,1,1
3,1,1,1
2,1,1,1
3,2,1,0
2,1,1,0
2,2,1,1
3,2,1,0
2,2,0,
3,2,1,1
3,2,1,1
3,1,1,0
3,2,1,0
2,1,1,0
3,1,1,1
3,2,1,1
3,2,1,0
3,2,1,1
3,2,1,1
3,2,1,1
; RUN;




%tablen(data=have, by=TM_group, 
     var=DEM_AGE DEM_SEX,
     type=2 2, outdoc=/home/fkhurshed/Demo1/TableNExample_delete.rtf);

Reeza_0-1715354418790.png

 

Change your outdoc in the code above and try again (everything else can stay the same). 

 


@Wolverine wrote:

As I recently posted here, I'm trying to create Table 1 for a research journal article. @Reeza pointed me to the Table 1 macro "TableN" and it looks like exactly what I need.

 

I downloaded the macro and ran it, and then I tried to call it based on the example provided.

 

/*Example macro call*/
/*%tablen(data=example, by=arm, 
     var=age date_on sex race1 smoke_st num_met,
     type=1 3 2, outdoc=~/ibm/example1.rtf);*/

/*My version*/
%tablen(data=have, by=TM_group, 
     var=DEM_AGE DEM_SEX,
     type=2 2, outdoc="C:\data_output\test.rtf);

But I got an error after "by TM_group": ERROR: All positional parameters must precede keyword parameters. I looked up the error and it has something to do with the commas between the parameters. After some trial and error of deleting commas, I got it to run without error, but it doesn't produce any output.

 

 

Sample data is provided below:

data have;
  infile datalines dsd dlm=',' truncover;
  input DEM_AGE DEM_SEX cohort_flag TM_group;
datalines;
3,1,1,0
2,1,1,1
3,2,1,1
3,2,1,1
3,2,1,0
2,2,1,1
2,1,1,1
3,1,1,1
2,1,1,1
3,2,1,0
2,1,1,0
2,2,1,1
3,2,1,0
2,2,0,
3,2,1,1
3,2,1,1
3,1,1,0
3,2,1,0
2,1,1,0
3,1,1,1
3,2,1,1
3,2,1,0
3,2,1,1
3,2,1,1
3,2,1,1
; RUN;

proc format library=temp;

value age2grp
1='1:Age Group <65'
2='2:Age Group [65,75)'
3='3:Age Group >=75'
.='Inapplicable/Missing';

value sex
.='Inapplicable/Missing'
1='1:Male'
2='2:Female'
value yesfmt
1='1:Yes'
2='2:No'
.='Inapplicable/Missing'
;
RUN;


 


 

Wolverine
Quartz | Level 8

I tried using the filename statement and getting the macro .sas file from the URL, but the result was the same. The macro still isn't compiling or executing.

 

I usually use a temp directory for my working files, so I added a LIBNAME statement. The only note I get in the log is that the Libref TEMP was successfully assigned.

 

Here is the entire log:



NOTE: Copyright (c) 2002-2012 by SAS Institute Inc., Cary, NC, USA.
NOTE: SAS (r) Proprietary Software 9.4 (TS1M4)
      Licensed to XXXXXXXX.
NOTE: This session is executing on the X64_10PRO  platform.

NOTE: Updated analytical products:

      SAS/STAT 14.2
      SAS/ETS 14.2
      SAS/OR 14.2
      SAS/IML 14.2
      SAS/QC 14.2

NOTE: Additional host information:

X64_10PRO WIN 10.0.22621  Workstation

NOTE: SAS initialization used:
      real time           1.13 seconds
      cpu time            0.18 seconds

1    LIBNAME temp "C:\Users\XXXXXXXX\SAStemp";
NOTE: Libref TEMP was successfully assigned as follows:
      Engine:        V9
      Physical Name: C:\Users\XXXXXXXX\SAStemp
2
3    filename tableN url
4     'https://gist.githubusercontent.com/statgeek/b55d964c99975c2ba23fa771afe616bc/raw/b30d55caf
4  ! 6ec4028f5afed3b260ce86b50419ddb/tablen.sas';
5
6    %include tableN;
4187
4188
4189   %tablen(data=temp.fall_summ_allyrs_cohort by TM_group,
4190       var = DEM_SEX DEM_AGE,
4191       type= 2 2, outdoc="C:\Users\XXXXXXXX\test.rtf";
4192   RUN;
Patrick
Opal | Level 21

@Wolverine Using below code I'm getting a result with your sample data.

Code run locally on a Windows laptop with SAS9.4M8 

What happens if you execute this code in your environment in a fresh new session? Only bit you need to end is the path "c:\temp\...." to something that's suitable for your environment.

Spoiler
data have;
  infile datalines dsd dlm=',' truncover;
  input DEM_AGE DEM_SEX cohort_flag TM_group;
  datalines;
3,1,1,0
2,1,1,1
3,2,1,1
3,2,1,1
3,2,1,0
2,2,1,1
2,1,1,1
3,1,1,1
2,1,1,1
3,2,1,0
2,1,1,0
2,2,1,1
3,2,1,0
2,2,0,
3,2,1,1
3,2,1,1
3,1,1,0
3,2,1,0
2,1,1,0
3,1,1,1
3,2,1,1
3,2,1,0
3,2,1,1
3,2,1,1
3,2,1,1
;
RUN;

proc format library=temp;
  value age2grp
    1='1:Age Group <65'
    2='2:Age Group [65,75)'
    3='3:Age Group >=75'
    .='Inapplicable/Missing'
  ;
  value sex
    1='1:Male'
    2='2:Female'
    .='Inapplicable/Missing'
  ;
  value yesfmt
    1='1:Yes'
    2='2:No'
    .='Inapplicable/Missing'
  ;
RUN;

filename tableN url 'https://communities.sas.com/kntur85557/attachments/kntur85557/library/4477/5/tablen_05102022.sas';
/*filename tableN url 'https://communities.sas.com/kntur85557/attachments/kntur85557/library/4477/5/tablen_032020_pharmasug.sas';*/
/*filename tableN url 'https://gist.githubusercontent.com/statgeek/b55d964c99975c2ba23fa771afe616bc/raw/b30d55caf6ec4028f5afed3b260ce86b50419ddb/tablen.sas';*/
%include tableN /source2;

filename mprint "c:\temp\gencode.sas";
options mprint mfile;
%tablen(
  data=have
  ,by=TM_group
  ,var=DEM_AGE DEM_SEX
  ,type=2 2, outdoc=C:\temp\test.rtf
  );

options nomfile;

Patrick_0-1715356340026.png

 

The code executes with Warnings!

It appears the code the macro generates changes the environment - like ODS LISTING CLOSE;

Below macro call with option MFILE set will write the generated code to file .../gencode.sas which you could use to further investigate what's happening. 

filename mprint "c:\temp\gencode.sas";
options mprint mfile;
%tablen(
  data=have
  ,by=TM_group
  ,var=DEM_AGE DEM_SEX
  ,type=2 2, outdoc=C:\temp\test.rtf
  );
options nomfile;

 

 

 

 

Wolverine
Quartz | Level 8

This works! It worked with the sample data, so I removed the datalines and added my real data to the data step and that works too! 😁

 

However, I need to restrict to certain cases in the file. Previously, I used "Where cohort_flag = 1;", but I don't know where to put that in this code.

Patrick
Opal | Level 21
One option:
…(data=have(where=(cohort_flag=1)),….
Wolverine
Quartz | Level 8

I'm getting an error that the dataset does not exist. It's reading it as if the name of the dataset is "have(where=(cohort_flag=1))". Here's the relevant portion of the code:

 

%tablen(
    data=have(where=(cohort_flag=1))
,by=TM_group

 

 

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
  • 17 replies
  • 576 views
  • 5 likes
  • 5 in conversation