SAS: Proc means output not as specified - sas

I want to output an extended Proc Means for my data. The standard is N, Min, Max, Std mean but I need also Median.
I have a lot of variables so I do not want to specify each individually after the output out= statement like median(var1)=var1_median etc.
The following does not work and just gives me the standard outputs:
proc means data=have n mean median std;
output out= want_means (drop=_type_ _freq_);
run;
this one also doesnt work:
proc means data=have n mean median std;
var volume price [xyz variables];
output out= want_means (drop=_type_ _freq_);
run;

I now use the following ,which works for me (note that I have to transpose it to have observations and not X variables...
proc means data=have;
output out= want(drop=_type_ _freq_)
n= mean= median= std= /autoname ;
run;
proc transpose data=want
out=want; run;

Related

Covert wide to long in sas when all the variable has the suffix needed

I want the first wide dataset to be as the second long datafile, I have thought about using array, but considering I have 100 variables (the example only have 2), do I need 100 arrays?
Could you let me know how to do?
Use a double transpose. First transpose to a tall structure. Then split the name into the basename and time. Then transpose again. Here is untested code since no example data was provided (only photographs).
proc transpose data=have out=tall ;
by id;
var _numeric_;
run;
data fixed ;
set tall ;
time = scan(_name_,-1,'_');
_name_ = substr(_name_,1,length(_name_)-length(time)-1);
run;
proc sort data=fixed ;
by id time;
run;
proc transpose data=fixed out=want ;
by id time ;
id _name_;
var col1;
run;

proc means output percentile statistics

proc means data = data1 stackODSoutput MIN P10 P25 P50 P75 P90 MAX N NMISS SUM nolabels maxdec=3;
var var1 var2;
output out = output;
run;
From the generated report, I can get all percentile and SUM. but the output data just provide me basic statistics with N, MIN, MAX, MEAN and std.
How can I also output the percentile and sum?
For output datasets in proc means, you need to specify which statistics you'd like within the output statement. Think of the proc statement as only controlling the visual output. Try this instead:
proc means data=sashelp.cars;
var horsepower MPG_City MPG_Highway;
output out=output
sum=
mean=
median=
std=
min=
max=
p10=
p25=
p75=
p90=
/ autoname
;
run;
Note that none of the statistics have anything after the =. The autoname option is automatically naming the statistic variables.
To make it easier to read, we can change the format of the output table. The naming convention of all variables is <variable>_<statistic>. Knowing this, we can transpose the table, separate out the variable and statistics from the name, then re-transpose it into a nicer format.
proc transpose data=output out=output_transposed;
var _NUMERIC_;
run;
data _want(index=(variable) );
set output_transposed;
Stat = scan(_NAME_, -1, '_');
Variable = tranwrd(_NAME_, cats('_', Stat), '');
keep Variable Stat COL1;
rename COL1 = Value;
run;
proc transpose data=_want out=want(drop=_NAME_);
by variable;
id stat;
var Value;
run;

How to filter a dataset according to its quantile

In the following code, how could I keep only the observations superior to the 95th quantile?
data test;
input business_ID $ count;
datalines;
'busi1' 2
'busi1' 10
'busi1' 4
'busi2' 1
'busi3' 2
'busi3' 1
;
run;
proc sort data = test;
by descending count;
run;
I don't know how to cleanly stock the quartile and then re-use it with an if condition.
Thanks
Edit : I can determine the quantile with this code :
proc means data=test noprint;
var count;
output out=quantile P75= / autoname;
run;
But how can I relate to it in the Test dataset so that I can select every observations above that quantile?
You could either read the value of the quantile in a macro variable to use in a subsequent if or where condition:
proc means data=test noprint;
var count;
output out=quantile P75= / autoname;
run;
data _null_;
set quantile;
call symput('quantile',count_p75);
run;
data test;
set test;
where count > &quantile.;
run;
or you could use an SQL subquery
proc means data=test noprint;
var count;
output out=quantile P75= / autoname;
run;
proc sql undo_policy=none;
create table test as
select *
from test
where count > (select count_p75 from quantile)
;
quit;
(Note that your question mentions the 95th quantile whereas your sample code mentions the 75th)
User2877959's solution is solid. Recently I did this with Proc Rank. The solution is a bit 'work around-y', but saves a lot of typing.
proc rank data=Input groups=1000 out=rank_out;
var var_to_rank;
ranks Rank_val;
run;
data seventy_five;
set rank_out;
if rank_val>750;
run;
More on Rank: http://documentation.sas.com/?docsetId=proc&docsetTarget=p0le3p5ngj1zlbn1mh3tistq9t76.htm&docsetVersion=9.4&locale=en

How to PROC PRINT only the sum of a column of data

In SAS, you can use PROC PRINT to sum a column and display the sum:
proc print data = dataset.project_out;
sum variable;
run;
How can I get this function to only print the sum line and not the rest of the data?
I don't think you can do it with proc print. The closest you can come is the empty var statement:
proc print data=sashelp.class;
var ;
sum age;
run;
But sum adds the sum variable to the var list.
You can certainly accomplish this a number of other ways.
PROC SQL is the one I'd use:
proc sql;
select sum(Age) from sashelp.class;
quit;
PROC REPORT, often called "pretty PROC PRINT", can do it also:
proc report data=sashelp.class;
columns age;
define age/analysis sum;
run;
PROC TABULATE can do it:
proc tabulate data=sashelp.class;
var age;
tables age*sum;
run;
PROC MEANS:
proc means data=sashelp.class sum;
var age;
run;
Etc., plenty of ways to do the same thing.

Using proc freq with repeated ID variables

I would like to use proq freq to count the number of food types that someone consumed on a specific day(fint variable). My data is in long format with repeated idno for the different food types and different number of interview dates. However SAS hangs and does not run the code. I have more than 300,000 datalines.Is there another way to do this?
proc freq;
tables idno*fint*foodtype / out=countft;
run;
I am a little unsure of your data structure, but proc means can also count.
Assuming that you have multiple dates for each person, and multiple food types for each date, you can use:
data dataset;
set dataset;
count=1;
run;
proc means data=dataset sum;
class idno fint foodtype;
var count;
output out=countft sum=counftpday;
run;
/* Usually you only want the lines with the largest _type_, so keep going here */
proc sql noprint;
select max(_type_) into :want from countft;
quit; /*This grabs the max _type_ from output file */
data countft;
set countft;
where _type_=&want.;
run;
Try a proc sql:
proc sql;
create table want as
select distinct idno, fint, foodtype, count(*) as count
from have
order by 1, 2, 3;
quit;
Worse case scenario, sort and count in a data step.
proc sort data=have;
by idno fint foodtype;
run;
data count;
set have;
by idno fint foodtype;
if first.foodtype then count=1;
else count+1;
if last.foodtype then output;
run;