Reputation: 31
I'm slicing data with proc SQL and group by for a report. Let's say my data consists of
I'll make a macro to slice the data by one of the (4) bins, animal type and get the averages of height, weight, etc. Then I'd like to stack all of them into one table, for that, I need the data to have a name column, to see what it was grouped by, say name = hair color or country of birth.
%macro slice(data, group);
proc sql;
create table &data._grpuped_by_&group.
as select
animal_type,
year_born,
&group as group,
'&group.' as name, /* this is the part i can't manage */
avg(heigth) as avg_height
from &data
group by 1, 2, 3, 4
;
quit;
%mend slice;
Let's say I want my data to be grouped by hair color and I would like to have a column that indicates that the data was sliced by that variable.
What I get is "&group as a group" all the hair colors in a column named "name" exactly like the column "group". What I would like to get is a column named "name" with variable hair color.
Upvotes: 2
Views: 173
Reputation: 27498
Proc TABULATE
with an OUT=
can capture all the groupings and continuous measures group-wise statistics in one step.
Example:
ods noresults;
%let GROUP_VARS = origin make type drivetrain enginesize;
%let STAT_VARS = msrp invoice weight length;
%let STATS = mean min;
proc tabulate data=sashelp.cars out=crossings ;
class &GROUP_VARS;
var msrp invoice weight length;
table
(&GROUP_VARS)
,
(&STAT_VARS) * (&STATS) N
;
run;
ods results;
data want;
length group_var $32 group_val $50;
set crossings;
if countc(_type_,'1') = 1 then do;
group_var = scan("&GROUP_VARS", index(_type_,"1"));
group_val = vvaluex(group_var);
end;
run;
Upvotes: 0
Reputation: 21264
A PROC MEANS
approach is here, no macros needed.
*variable list;
%let var= sex age;
*summary statistics;
ods select none;
proc means data=sashelp.class stackods n mean min median max;
class &var. / mlf;
ways 1;
var weight height;
ods output summary=want1;
run;
ods select all;
data want2;
set want1;
*list of variables;
array _v(*) $ &var.;
*clean up to get variable name and value into single columns;
do i=1 to dim(_v);
if not missing(_v(i)) then
do;
variableName=vname(_v(i));
variableValue=_v(i);
end;
end;
run;
proc print data=want2;
var variable: N Mean Min Median Max;
run;
Results in:
Obs Variable variableName variableValue N Mean Min Median Max
1 Weight Age 11 2 67.750000 50.500000 67.750000 85.000000
2 Height Age 11 2 54.400000 51.300000 54.400000 57.500000
3 Weight Age 12 5 94.400000 77.000000 84.500000 128.000000
4 Height Age 12 5 59.440000 56.300000 59.000000 64.800000
5 Weight Age 13 3 88.666667 84.000000 84.000000 98.000000
6 Height Age 13 3 61.433333 56.500000 62.500000 65.300000
7 Weight Age 14 4 101.875000 90.000000 102.500000 112.500000
8 Height Age 14 4 64.900000 62.800000 63.900000 69.000000
9 Weight Age 15 4 117.375000 112.000000 112.250000 133.000000
10 Height Age 15 4 65.625000 62.500000 66.500000 67.000000
11 Weight Age 16 1 150.000000 150.000000 150.000000 150.000000
12 Height Age 16 1 72.000000 72.000000 72.000000 72.000000
13 Weight Sex F 9 90.111111 50.500000 90.000000 112.500000
14 Height Sex F 9 60.588889 51.300000 62.500000 66.500000
15 Weight Sex M 10 108.950000 83.000000 107.250000 150.000000
16 Height Sex M 10 63.910000 57.300000 64.150000 72.000000
Upvotes: 1
Reputation: 1770
An error has occured cause of incorrect use of quoting macro variable. This article says:
Note: The title is enclosed in double quotation marks. In quoted strings in open code, the macro processor resolves macro variable references within double quotation marks but not within single quotation marks.
So, the correct solution:
%macro slice(data, group);
proc sql;
create table &data._grpuped_by_&group.
as select
animal_type,
year_born,
&group as group,
"&group." as name, /* here was the mistake, not '&group.' */
avg(heigth) as avg_height
from &data
group by 1, 2, 3, 4
;
quit;
%mend slice;
Upvotes: 0