Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How do I add blank rows to a SAS table?

Status
Not open for further replies.

jhikagali

Programmer
Feb 10, 2006
4
US
I have been head-banging on this one for several days. Seems there should just be a command like "append blank". I have been working with PUTVARC, but SAS keeps complaining about the syntax, and I cannot figure out what I'm doing wrong. Does someone out there have a way of doing this with some code examples? Here is the code I have tried that doesn't work:

options nofmterr yearcutoff=1910 mprint symbolgen;

DATA RESULTS;
LENGTH CATEGORY $42.;
LENGTH REGION $13.;
LENGTH RANGE $42.;
LENGTH POP80 8.;
LENGTH POP81 8.;
LENGTH POP82 8.;
LENGTH POP83 8.;
LENGTH POP84 8.;
LENGTH POP85 8.;
LENGTH POP86 8.;
LENGTH POP87 8.;
LENGTH POP88 8.;
LENGTH POP89 8.;
RUN;

DATA ONE;
SET RESULTS;
CATEGORY='RACE';
REGION='APACHE';
RANGE='WHITE NON-HISPANIC';
RUN;

TERM:
tidnum=open('work.one','u');
vnum=varnum('work.one','RANGE');
rc=locatec(tidnum,vnum,'WHITE NON-HISPANIC','u');
if (rc>0) then
do;
call putvarc(tidnum,vnum,'BLACK NON-HISPANIC');
rc=update(tidnum);
end;
rc=close(tidnum);
RETURN;


And here is the log I get from that code:

NOTE: SAS 9.1.3 Service Pack 2

NOTE: SAS initialization used:
real time 2.43 seconds
cpu time 0.98 seconds


1 options nofmterr yearcutoff=1910 mprint symbolgen;
2
3 DATA RESULTS;
4 LENGTH CATEGORY $42.;
5 LENGTH REGION $13.;
6 LENGTH RANGE $42.;
7 LENGTH POP80 8.;
8 LENGTH POP81 8.;
9 LENGTH POP82 8.;
10 LENGTH POP83 8.;
11 LENGTH POP84 8.;
12 LENGTH POP85 8.;
13 LENGTH POP86 8.;
14 LENGTH POP87 8.;
15 LENGTH POP88 8.;
16 LENGTH POP89 8.;
17 RUN;

NOTE: Variable CATEGORY is uninitialized.
NOTE: Variable REGION is uninitialized.
NOTE: Variable RANGE is uninitialized.
NOTE: Variable POP80 is uninitialized.
NOTE: Variable POP81 is uninitialized.
NOTE: Variable POP82 is uninitialized.
NOTE: Variable POP83 is uninitialized.
NOTE: Variable POP84 is uninitialized.
NOTE: Variable POP85 is uninitialized.
NOTE: Variable POP86 is uninitialized.
NOTE: Variable POP87 is uninitialized.
NOTE: Variable POP88 is uninitialized.
NOTE: Variable POP89 is uninitialized.
NOTE: The data set WORK.RESULTS has 1 observations and 13 variables.
NOTE: DATA statement used (Total process time):
real time 0.26 seconds
cpu time 0.06 seconds


18
19 DATA ONE;
20 SET RESULTS;
21 CATEGORY='RACE';
22 REGION='APACHE';
23 RANGE='WHITE NON-HISPANIC';
24 RUN;

NOTE: There were 1 observations read from the data set WORK.RESULTS.
NOTE: The data set WORK.ONE has 1 observations and 13 variables.
NOTE: DATA statement used (Total process time):
real time 0.04 seconds
cpu time 0.03 seconds


25
26 TERM:
27 tidnum=open('work.one','u');
------
180

ERROR 180-322: Statement is not valid or it is used out of proper order.

28 vnum=varnum('work.one','RANGE');
----
180

ERROR 180-322: Statement is not valid or it is used out of proper order.

29 rc=locatec(tidnum,vnum,'WHITE NON-HISPANIC','u');
--
180

ERROR 180-322: Statement is not valid or it is used out of proper order.

30 if (rc>0) then
--
180
ERROR 180-322: Statement is not valid or it is used out of proper order.

31 do;

32 call putvarc(tidnum,vnum,'BLACK NON-HISPANIC');
----
180

ERROR 180-322: Statement is not valid or it is used out of proper order.

33 rc=update(tidnum);
--
180

ERROR 180-322: Statement is not valid or it is used out of proper order.

34 end;
---
180

ERROR 180-322: Statement is not valid or it is used out of proper order.

35 rc=close(tidnum);
--
180

ERROR 180-322: Statement is not valid or it is used out of proper order.

36 RETURN;
------
180

ERROR 180-322: Statement is not valid or it is used out of proper order.


I don't know why it keeps saying the statements are not valid or are used out of proper order.
 
It looks like you are using base sas in an AF app. You have to use the base sas code between Submit: Continue; tags.
On another note why do you need to add blank records to a sas ds? Usually that is not recommended. Do you have to add a blank line to a listbox that you fill by reading a sas dataset?

The way I would add a blank line in your case is as follows:
DATA ONE;
SET RESULTS;
output;
CATEGORY='RACE';
REGION='APACHE';
RANGE='WHITE NON-HISPANIC';
output;
RUN;
 
Yes, you are right of course. Thanks. I realized that this approach is rather unusual, but what I am trying to do is build an application for construction of some customized population tables for the state of Arizona. I work for the state health dept., and different programs want different things. (For example, they use different age categories.) Rather than write applications that depend upon pre-fabricated output tables, I would rather build the customized output tables using SAS as well as fill them in with SAS all in the same application. It is a completely canned program. That way, once it is written, I only have to change one thing every year, and it will produce updated annual population charts for every program that uses them. I have been having a hard time doing some of the most fundamental things. Your approach, actually, was one that I ended up trying with success over the weekend. Here is the code for one of the simpler tables using this method:

LIBNAME TEMP 'C:\TEMP';
options nofmterr yearcutoff=1910 mprint symbolgen;

%MACRO DOIT1(VALUE1);
DATA ONE;
SET ONE;
RANGE=&VALUE1;
RUN;

PROC APPEND BASE=TWO DATA=ONE;
RUN;
%MEND DOIT1;

%MACRO DOIT2(VALUE2);
DATA TWO;
SET TWO;
IF REGION~=&VALUE2 THEN REGION=&VALUE2;
RUN;

PROC APPEND BASE=THREE DATA=TWO;
RUN;
%MEND DOIT2;

%MACRO DOIT3;
%DOIT2('COCHISE');
%DOIT2('COCONINO');
%DOIT2('GILA');
%DOIT2('GRAHAM');
%DOIT2('GREENLEE');
%DOIT2('LAPAZ');
%DOIT2('MARICOPA');
%DOIT2('MOHAVE');
%DOIT2('NAVAJO');
%DOIT2('PIMA');
%DOIT2('PINAL');
%DOIT2('SANTA CRUZ');
%DOIT2('YAVAPAI');
%DOIT2('YUMA');
%DOIT2('UNKNOWN');
%DOIT2('ARIZONA TOTAL');
%MEND DOIT3;


/* Creates rows for race categories by county and for the state as a whole */
DATA ONE;
LENGTH CATEGORY $42.;
LENGTH REGION $13.;
LENGTH RANGE $42.;
LENGTH POP80 8.;
LENGTH POP81 8.;
LENGTH POP82 8.;
LENGTH POP83 8.;
LENGTH POP84 8.;
LENGTH POP85 8.;
LENGTH POP86 8.;
LENGTH POP87 8.;
LENGTH POP88 8.;
LENGTH POP89 8.;
LENGTH POP90 8.;
LENGTH POP91 8.;
LENGTH POP92 8.;
LENGTH POP93 8.;
LENGTH POP94 8.;
LENGTH POP95 8.;
LENGTH POP96 8.;
LENGTH POP97 8.;
LENGTH POP98 8.;
LENGTH POP99 8.;
LENGTH POP00 8.;
LENGTH POP01 8.;
LENGTH POP02 8.;
LENGTH POP03 8.;
LENGTH POP04 8.;
LENGTH POP05 8.;
LENGTH POP06 8.;
CATEGORY='RACE';
REGION='APACHE';
RANGE='WHITE NON-HISPANIC';
RUN;

PROC APPEND BASE=TWO DATA=ONE;
RUN;


%DOIT1('BLACK NON-HISPANIC');
%DOIT1('HISPANIC');
%DOIT1('ASIAN/PACIFIC ISLANDER NON-HISPANIC');
%DOIT1('AMERICAN INDIAN/ALASKA NATIVE NON-HISPANIC');
%DOIT1('OTHER/UNKNOWN');
%DOIT1('TOTAL ALL RACES');

PROC APPEND BASE=THREE DATA=TWO;
RUN;

%DOIT3;
RUN;

/* Creates rows for age categories by county and for the state as a whole */
DATA ONE;
SET ONE;
CATEGORY='AGE';
REGION='APACHE';
RANGE='UNDER 2';
RUN;

PROC APPEND BASE=TWO DATA=ONE;
RUN;

%DOIT1('2-12');
%DOIT1('13-19');
%DOIT1('20-24');
%DOIT1('25-29');
%DOIT1('30-34');
%DOIT1('35-39');
%DOIT1('40-44');
%DOIT1('45-49');
%DOIT1('50-54');
%DOIT1('55-59');
%DOIT1('60-64');
%DOIT1('65 AND ABOVE');
%DOIT1('TOTAL ALL AGES');

DATA TWO;
SET TWO;
IF RXMATCH(RXPARSE('HISPANIC'),RANGE)>0 OR RXMATCH(RXPARSE('OTHER'),RANGE)>0 OR RXMATCH(RXPARSE('RACES'),RANGE)>0 THEN DELETE;
RUN;

PROC APPEND BASE=THREE DATA=TWO;
RUN;

%DOIT3;
RUN;

/* Creates rows for risk categories by county and for the state as a whole */
DATA ONE;
SET ONE;
CATEGORY='RISK';
REGION='APACHE';
RANGE='MSM';
RUN;

PROC APPEND BASE=TWO DATA=ONE;
RUN;

%DOIT1('IVDU');
%DOIT1('MSM/IVDU');
%DOIT1('HETEROSEXUAL');
%DOIT1('HEMOPILIA/TRANSFUSION/TRANSPLANT/OTHER');
%DOIT1('RISK NOT REPORTED/UNIDENTIFIED');
%DOIT1('TOTAL ALL RISKS');

DATA TWO;
SET TWO;
IF RXMATCH(RXPARSE('9'),RANGE)>0 OR RXMATCH(RXPARSE('4'),RANGE)>0 OR RXMATCH(RXPARSE('65'),RANGE)>0 OR RXMATCH(RXPARSE('2'),RANGE)>0 OR RXMATCH(RXPARSE('AGES'),RANGE)>0 THEN DELETE;
RUN;

PROC APPEND BASE=THREE DATA=TWO;
RUN;

%DOIT3;
RUN;

/* Creates rows for SEX categories by county and for the state as a whole */
DATA ONE;
SET ONE;
CATEGORY='SEX';
REGION='APACHE';
RANGE='MALE';
RUN;

PROC APPEND BASE=TWO DATA=ONE;
RUN;

%DOIT1('FEMALE');
%DOIT1('TOTAL ALL SEXES');

DATA TWO;
SET TWO;
IF RXMATCH(RXPARSE('MALE'),RANGE)>0 OR RXMATCH(RXPARSE('SEXES'),RANGE)>0;
RUN;

PROC APPEND BASE=THREE DATA=TWO;
RUN;

%DOIT3;
RUN;

From this point, I can add in macros that sum and fill in annual population values for each year from, in this case, 1990 through the current year. So each row will be summed from a source table issued by the census as the table is constructed in SAS.

Regarding your response: Base SAS and AF? What is that, which am I using, and where can I read about this? I am guessing that one of these may have to do with some kind of specialized application similar to building forms for data entry, etc.

Thanks for your help.
 
from what i can work out, you want to store population data at 4 different levels(?) - age, sex, ethnicity & risk, for each region and year.

So,

Table: POP_AGE
- region
- age_group
- year
- population

Table: POP_SEX
- region
- sex
- year
- population

Table: POP_ETHNICITY
- region
- ethnicity
- year
- population

Table: POP_RISK
- region
- risk_type
- year
- population

there's no need to insert missing values. you can use PROC SQL (wrapped in macro's if you wish) to insert the data.

i would use multi label formats to do the grouping at different levels or sum it. if you have missing populations for certain age groups but still need the total population for all ages then thats a different story. if thats the case then have another table to give the total populations.

Table: POP
- region
- year
- population

additional years can be added without any structural changes to the tables.
 
You are one step ahead of me on this. I had just begun to look at Proc SQL as a method of doing what I was trying to do. As a result of your suggestion, I added the following steps and have been able to successfully sum the column:

DATA COUNTING;
SET POPS.POPTOT;
IF COUNTY='APACHE' AND RACECAT='1';
RUN;

proc sql;
select sum(pop90) as tot90 from COUNTING;
run;

I feel that this problem has been resolved. And thank uyou very much for your help.
While your suggested code for generating tables would work better than what I am using, and is certainly a much simpler and more elegant solution, I have the problem that the various programs I am generating this for need to have their results in a specified format. So I have to take it from the Census source file (flat file in one format), import it, prepare output tables that match the requirements of each program (which vary by age category, risk groups, etc), and then count and fill in to those different tables. And I have to produce an updated version for general use each year as the Census releases its annual population estimates. This single task will save hours and hours of work for many people. But not for me because I have to write it.

Can you suggest some syntax for issuing a call symput statment that captures the results of the PROC SQL given above? Or is there another way to direct the PROC SQL returns to the output tables? This is one thing which I have repeatedly attempted to do in SAS, but never been able to get to work.
 
You can use the "INTO:" to store stuff in a macro variable from within PROC SQL:
e.g.
Code:
%global myMacro;
proc sql;
   select sum(pop90) into:myMacro as tot90 from COUNTING;
run;
I'm not sure why you would need to.

I'm guessing you have some numerator data that you want to combine with your population data then generate some reports?

i would:
- create your population datasets
- load the data into your population datasets from your external files
- summarize your numerator data, if need be
- combine your numerator data with your population data using either view's or temp datasets
- use proc's to generate the reports e.g. proc tabulate etc
if need be, use proc transpose

you don't need to store the data in the same layout as your reports

if you need help importing the census data, then show us what the input data file looks like and how you want the output dataset to look.

cheers,
dan
 
It is funny that people keep asking me why I would want to do that. Either I'm missing something pretty basic with SAS, or I'm trying to do something that has never been done before (which I doubt). SO . . .

Format of input data file:

04001 011 109 105 94 91 87 85 82 74 70 65

And so it goes, one observation per line in a flat file that is several 100,000 lines deep. Here is the import statement I'm using, and it works just fine:

DATA POP90TO06;
INFILE 'g:\groups\hiv2\robert\population data\population estimates\Arizona_90-06_by_year.txt' FIRSTOBS=1;
INPUT +2 CNTY $3. AGE 2. RACESEX $1. HISP $1. POP90 8. POP91 8. POP92 8. POP93 8. POP94 8. POP95 8. POP96 8. POP97 8. POP98 8. POP99 8. POP00 8. POP01 8. POP02 8. POP03 8. POP04 8. POP05 8. POP06 8.;
RUN;


Now, there are several output formats, but I will give you only one - for HIV/AIDS surveillance. The best way to see the required table structure is to run the following code:

LIBNAME TEMP 'C:\TEMP';
options nofmterr yearcutoff=1910 mprint symbolgen;

%MACRO DOIT1(VALUE1);
DATA ONE;
SET ONE;
RANGE=&VALUE1;
RUN;

PROC APPEND BASE=TWO DATA=ONE;
RUN;
%MEND DOIT1;

%MACRO DOIT2(VALUE2);
DATA TWO;
SET TWO;
IF REGION~=&VALUE2 THEN REGION=&VALUE2;
RUN;

PROC APPEND BASE=THREE DATA=TWO;
RUN;
%MEND DOIT2;

%MACRO DOIT3(VALUE3A,VALUE3B,VALUE3C);
DATA ONE;
SET ONE;
CATEGORY=&VALUE3A;
REGION=&VALUE3B;
RANGE=&VALUE3C;
RUN;
PROC APPEND BASE=TWO DATA=ONE;
RUN;
%MEND DOIT3;

%MACRO DOIT4(VALUE3A,VALUE3B);
DATA TWO;
SET TWO;
CATEGORY=&VALUE3A;
REGION=&VALUE3B;
RUN;
PROC APPEND BASE=THREE DATA=TWO;
RUN;
%MEND DOIT4;

%MACRO RACE;
%DOIT1('BLACK NON-HISPANIC');
%DOIT1('HISPANIC');
%DOIT1('ASIAN/PACIFIC ISLANDER NON-HISPANIC');
%DOIT1('AMERICAN INDIAN/ALASKA NATIVE NON-HISPANIC');
%DOIT1('OTHER/UNKNOWN');
%DOIT1('TOTAL ALL RACES');
DATA TWO;
SET TWO;
IF RXMATCH(RXPARSE('HISPANIC'),RANGE)>0 OR RXMATCH(RXPARSE('UNKNOWN'),RANGE)>0 OR RXMATCH(RXPARSE('RACE'),RANGE)>0;
RUN;
PROC APPEND BASE=THREE DATA=TWO;
RUN;
%MEND RACE;

%MACRO AGE;
%DOIT1('2-12');
%DOIT1('13-19');
%DOIT1('20-24');
%DOIT1('25-29');
%DOIT1('30-34');
%DOIT1('35-39');
%DOIT1('40-44');
%DOIT1('45-49');
%DOIT1('50-54');
%DOIT1('55-59');
%DOIT1('60-64');
%DOIT1('65 AND ABOVE');
%DOIT1('TOTAL ALL AGES');
DATA TWO;
SET TWO;
IF RXMATCH(RXPARSE('5'),RANGE)>0 OR RXMATCH(RXPARSE('4'),RANGE)>0 OR RXMATCH(RXPARSE('9'),RANGE)>0 OR RXMATCH(RXPARSE('2'),RANGE)>0 OR RXMATCH(RXPARSE('5'),RANGE)>0 OR RXMATCH(RXPARSE('AGES'),RANGE)>0;
RUN;
PROC APPEND BASE=THREE DATA=TWO;
RUN;
%MEND AGE;

%MACRO SEX;
%DOIT1('FEMALE');
%DOIT1('TOTAL ALL SEXES');
DATA TWO;
SET TWO;
IF RXMATCH(RXPARSE('MALE'),RANGE)>0 OR RXMATCH(RXPARSE('SEXES'),RANGE)>0;
RUN;
PROC APPEND BASE=THREE DATA=TWO;
RUN;
%MEND SEX;

%MACRO COUNTY;
%DOIT2('COCHISE');
%DOIT2('COCONINO');
%DOIT2('GILA');
%DOIT2('GRAHAM');
%DOIT2('GREENLEE');
%DOIT2('LAPAZ');
%DOIT2('MARICOPA');
%DOIT2('MOHAVE');
%DOIT2('NAVAJO');
%DOIT2('PIMA');
%DOIT2('PINAL');
%DOIT2('SANTA CRUZ');
%DOIT2('YAVAPAI');
%DOIT2('YUMA');
%DOIT2('UNKNOWN');
%DOIT2('ARIZONA TOTAL');
%MEND COUNTY;

DATA ONE;
LENGTH CATEGORY $42.;
LENGTH REGION $13.;
LENGTH RANGE $42.;
LENGTH POP80 8.;
LENGTH POP81 8.;
LENGTH POP82 8.;
LENGTH POP83 8.;
LENGTH POP84 8.;
LENGTH POP85 8.;
LENGTH POP86 8.;
LENGTH POP87 8.;
LENGTH POP88 8.;
LENGTH POP89 8.;
LENGTH POP90 8.;
LENGTH POP91 8.;
LENGTH POP92 8.;
LENGTH POP93 8.;
LENGTH POP94 8.;
LENGTH POP95 8.;
LENGTH POP96 8.;
LENGTH POP97 8.;
LENGTH POP98 8.;
LENGTH POP99 8.;
LENGTH POP00 8.;
LENGTH POP01 8.;
LENGTH POP02 8.;
LENGTH POP03 8.;
LENGTH POP04 8.;
LENGTH POP05 8.;
LENGTH POP06 8.;
RUN;

/* Creates rows for race categories by county and for the state as a whole */
%DOIT3('RACE','APACHE','WHITE NON-HISPANIC');
%RACE;
%COUNTY;

/* Creates rows for age categories by county and for the state as a whole */
%DOIT3('AGE','APACHE','UNDER 2');
%AGE;
%COUNTY;

/* Creates rows for SEX categories by county and for the state as a whole */
%DOIT3('SEX','APACHE','MALE');
%SEX;
%COUNTY;

/* Creates rows for MALE RACE categories by county and for the state as a whole */
%DOIT3('MALE','APACHE','WHITE NON-HISPANIC');
%RACE;
%COUNTY;

/* Creates rows for MALE AGE categories by county and for the state as a whole */
%DOIT3('MALE','APACHE','UNDER 2');
%AGE;
%COUNTY;

/* Creates rows for FEMALE RACE categories by county and for the state as a whole */
%DOIT3('FEMALE','APACHE','WHITE NON-HISPANIC');
%RACE;
%COUNTY;

/* Creates rows for FEMALE AGE categories by county and for the state as a whole */
%DOIT3('FEMALE','APACHE','UNDER 2');
%AGE;
%COUNTY;

/* Creates rows for WHITE NON-HISPANIC AGE categories by county and for the state as a whole */
%DOIT4('WHITE NON-HISPANIC','APACHE');
%COUNTY;

/* Creates rows for BLACK NON-HISPANIC AGE categories by county and for the state as a whole */
%DOIT4('BLACK NON-HISPANIC','APACHE');
%COUNTY;

/* Creates rows for HISPANIC AGE categories by county and for the state as a whole */
%DOIT4('HISPANIC','APACHE');
%COUNTY;

/* Creates rows for ASIAN/PACIFIC ISLANDER NON-HISPANIC AGE categories by county and for the state as a whole */
%DOIT4('ASIAN/PACIFIC ISLANDER NON-HISPANIC','APACHE');
%COUNTY;

/* Creates rows for AMERICAN INDIAN/ALASKA NATIVE NON-HISPANIC AGE categories by county and for the state as a whole */
%DOIT4('AMERICAN INDIAN/ALASKA NATIVE NON-HISPANIC','APACHE');
%COUNTY;

DATA TEMP.RESULTS;
SET THREE;
RUN;

Examine the resulting table TEMP.RESULTS for the required structure. It is 2312 records deep.

Now, I need to count and fill in for each annual population value, into each row. The best way I can think of to do that is as I am generating the table. This is an ideal situation for using a macro. The macro would subset from the source population table selecting values appropriate only for the row being generated, sum each population column, capture the resulting sum values, and fill in each column of the row as it is being generated. Kind of a macro'd array function.

If I understand you correctly, you are suggesting a simpler method. Even with a required table structure this complex? Well, there's always another way to skin the cat, so to speak. But if you see ways that you think are better, let me know, please. I am always learning new tricks in SAS every day.

Actually this is a prototype program to works out the methodology for doing things like this. That methodology can and will be used in much more complex programs to generate similarly structured output files. We use other non-SAS programs that do this sort of thing to generate our surveillance epidemiology - annual diagnosis frequencies, prevalence counts, incidence counts, etc. And they are run monthly, weekly, daily. So once I find a way to do this, I can easily produce SAS programs that will generate all of the epidemiology, and which can be batch scheduled to run automatically. The epidemiologists then are freed up to do higher analysis and reports, rather than spend their time running routine queries manually.

I hope that shows you what I am trying to do. I will try your suggested code in the program as it now exists. Thanks. Sorry this is so long a response. But it is a very challenging objective - at least for me it is.


 
Hiya,
I think the reason why people keep asking you why you are doing this is a common thing I've found when dealing with requests. When someone says "What are you trying to do?" we frequently get an answer like "I'm trying to lift my left foot up and put it in front of my right foot". The answer we're looking for is more like "I'm trying to walk". :)

One question you asked earlier was how to direct the Proc SQL data to a macro variable or a table. You were given how to direct to a macro variable, but not a table. So, just in case you don't know that syntax, it is:-
Code:
 proc sql;
    create table mydata.table2 as
    select *
    from mydata.table1
    ;
 quit;

It looks to me like you are trying to summarise data to every possible combination of your category variables, and have all the data in one table. There is a way to do this in a Proc step, using Proc Summary (or proc means).
Code:
  proc summary data=mydata.table1;
    by age sex area race;
    var pop1 pop2 pop3;
    output out=mydata.table2 sum=;
  run;
[code]
Here, without using the NWAY option in the proc summary statement, you get the sum for each available combination of the by variables.  the VAR variables are all summed (designated by the sum= on the output line) and they retain their original variable names.   There will be two extra variables on the output table, _freq_ and _type_.  The freq variable I beleive is a count of how many records were in that by group, and the _type_ variable shows what level of BY the record is calculated for.  You'll need to read the doco on Proc MEANS in order to get the full run down on how to interpret _type_.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top