How to do sub plot using sas - sas

I want to make a simple time series line plot without highlighting any dots on the line. I can plot var1 and var2 using the following code.
title "Title";
proc gplot data=test;
plot var1 *var2 /overlay grid hminor=0 ;
run;
quit;
However I want to add another variable into the plot. I tried the following code. Because the scale of var1 and var3 are quite large, so var3 are not properly scaled in the graph. Can anyone teach me how to use different scale for var1 and var3 please.
title "Title";
proc gplot data=Test;
plot var1 *var2 Var3*var2 /overlay grid hminor=0 ;
run;
quit;
Additionally, may I ask whether sas can do subplot as matlab please. Essentially, I got one big graph with two separate sub-graph. If possible, please teach me how to achieve this. I tried vpercent = 50, but it seems there are something wrong in my code.
proc gplot data=Test vpercent=50;
plot VAR1 *VAR2 VAR3*VAR2 /overlay grid hminor=0 ;
run;
quit;
With Thanks

Assuming I understand what you mean, if you have access to SGPLOT you can specify that X3 should be on a different axis. Here's an example with the SASHELP.STOCKS data which plots the open price on one Y axis and then the trade volume on the second Y axis.
proc sgplot data=sashelp.stocks;
where stock='IBM';
series x=date y=open;
series x=date y=volume/y2axis;
run;quit;

Here is some SAS code that builds on Reeza's excellent example and suggestion to use SGPANEL. See the PANELBY statement and the options used there.
*** SUBSET DATA AND SORT ***;
proc sort data=sashelp.stocks out=ibm;
where stock='IBM';
by date;
run;
*** TRANSPOSE DATA FROM "SHORT-AND-WIDE" TO "LONG-AND-THIN" ***;
proc transpose data=ibm out=ibm_t;
by date;
var open volume;
run;
proc sgpanel data=ibm_t;
*** ROW LATTICE OPTION STACKS PLOTS ***;
*** UNISCALE OPTION LETS EACH PANEL HAVE IT'S OWN SCALE ***;
*** NOVARNAME SUPPRESSES LABEL FOR THE Y-AXIS ON THE RIGHT SIDE ***;
panelby _name_ / layout=rowlattice uniscale=column novarname;
series x=date y=col1;
*** SUPPRESS LABEL FOR THE Y-AXIS ON THE LEFT SIDE ***;
rowaxis display=(nolabel);
run;

Related

How to export editor code in SAS to word (rtf) file with tables

I have this code in SAS for an assignment. I am learning SAS and have completed all of the items already coded for and successfully have reviewed the output in the log and the results tab of SAS. I have the code included below:
ods listing close;
ods rtf file="C:\Users\barnedsm\Desktop\SAS
\Homework 8 hm.rtf" style=htmlblue;
1. read in the data into SAS to get a SAS data set trees using the proc import statement. (5
points)
proc import
datafile="C:\Users\barnedsm\Desktop\SAS\Trees.csv"
dbms=csv
out=trees;
run;
2. print the first 5 observations of the data set using the proc print statement. (5 points)
proc print data=trees (obs=5);
run;
3. get the summary for the three variables (Girth, Height and Volume) of the data using
the proc means statement. (5 points)
proc means data=trees;
var Girth Height Volume;
run;
4. sort the data by Girth, Height and Volume variables. (1.5 bonus points)
Girth
proc sort data=trees out=trees;
by Girth;
proc print data=trees (obs=5);
run;
Height
proc sort data=trees out=trees;
by Height;
proc print data=trees (obs=5);
run;
Volume
proc sort data=trees out=trees;
by Volume;
proc print data=trees (obs=5);
run;
Three Variables
proc sort data=trees out=trees;
by Girth Height Volume;
proc print data=trees (obs=5);
run;
libname mylibr "C:\Users\barnedsm\Desktop\SAS";
data mylibr.trees_permanent;
set trees;
run;
5. read in the data into SAS to get a SAS data set ToothGrowth using the proc import
statement. (5 points)
proc import
datafile="C:\Users\barnedsm\Desktop\SAS\ToothGrowth.csv"
dbms=csv
out=tooth;
proc print data=tooth (obs=5);
run;
6. create two SAS data sets ToothGrowth_OJ and ToothGrowth_VC for the animals with the
delivery method orange juice and ascorbic acid, respectively. (5 points)
data ToothGrowth_OJ;
set tooth;
where (supp="OJ");
proc print data=ToothGrowth_OJ (obs=5);
run;
data ToothGrowth_VC;
set tooth;
where (supp="VC");
proc print data=ToothGrowth_VC (obs=5);
run;
7. save the two SAS data sets in a permanent folder on your computer. (5 points)
libname mylibr "C:\Users\barnedsm\Desktop\SAS";
data mylibr.ToothGrowth_OJ_permanent;
set ToothGrowth_OJ;
run;
libname mylibr "C:\Users\barnedsm\Desktop\SAS";
data mylibr.ToothGrowth_VC_permanent;
set ToothGrowth_VC;
run;
ods rtf close;
ods listing;
This works just fine, giving me an output with tables, but I want the SAS code from the editor included, which is the code above. How would I accomplish this? This is my first time using SAS, so I am very new.
The picture is one of the charts that was outputted, so the code works. But I'd like the SAS code included in the exported word (rtf) file. I have tried also removing the ads listing code, but it made no difference. Can anyone point out why my code is not included or direct me on how to do so. I mostly use R and R Studio, so this exporting format is new to me.

Logistic regression with BY statement ERROR message

I'm currently working on a SAS program that processes 50 logistic regression for 50 different samples. I previously had help on this thread (How to loop a logistic regression n number of times?), people advised me to use a BY statement to avoid looping this process n times. Works really well but I get this ERROR MESSAGE:
ERROR: No valid observations due either to missing values in the response, explanatory, frequency, or weight variable, or to
nonpositive frequency or weight values.
NOTE: The above message was for the following BY group:
Sample Replicate Number=.
You'll find my code below, if any of you have an idea of where does it come from, I'm open to anything, thank you in advance!
proc surveyselect data=TOP_1 NOPRINT out=ALEA_1
seed=0
method=urs
outhits
reps=5
n=300;
run;
proc surveyselect data=TOP_0 NOPRINT out=ALEA_0
seed=0
method=urs
outhits
reps=5
n=300;
run;
PROC SQL;
CREATE TABLE APPEND_TABLE As
SELECT * FROM ALEA_1
OUTER UNION CORR
SELECT * FROM ALEA_0;
QUIT;
/* Régression logistique*/
DATA WORK.TMP0TempTableAddtnlPredictData;
SET WORK.APPEND_TABLE(IN=__ORIG) WORK.BASE_PREDICT_2;
__FLAG=__ORIG;
__DEP=TOP_CREDIT_HABITAT_2017;
if not __FLAG then TOP_CREDIT_HABITAT_2017=.;
RUN;
PROC SQL;
CREATE VIEW WORK.SORTTempTableSorted AS
SELECT *
FROM WORK.TMP0TempTableAddtnlPredictData
ORDER BY REPLICATE;
QUIT;
TITLE;
TITLE1 "Résultats de la régression logistique";
FOOTNOTE;
FOOTNOTE1 "Généré par le Système SAS (&_SASSERVERNAME, &SYSSCPL) le %TRIM(%QSYSFUNC(DATE(), NLDATE20.)) à %TRIM(%SYSFUNC(TIME(), TIMEAMPM12.))";
PROC LOGISTIC DATA=WORK.SORTTempTableSorted
PLOTS(ONLY)=ROC
;
By Replicate;
CLASS age_classe (PARAM=EFFECT) Flag_bq_principale (PARAM=EFFECT) flag_univers_detenus (PARAM=EFFECT) csp_1 (PARAM=EFFECT) SGMT_FIDELITE (PARAM=EFFECT) situ_fam_1 (PARAM=EFFECT);
MODEL TOP_CREDIT_HABITAT_2017 (Event = '1') [...6## Heading ##] /
SELECTION=STEPWISE
SLE=0.1
SLS=0.1
INCLUDE=0
LINK=LOGIT
;
OUTPUT OUT=WORK.PREDLogRegPredictions(LABEL="Statistiques et prédictions de régression logistique pour WORK.APPEND_TABLE" WHERE=(NOT ws__FLAG))
PREDPROBS=INDIVIDUAL;
RUN;
QUIT;
DATA WORK.PREDLogRegPredictions;
set WORK.PREDLogRegPredictions;
TOP_CREDIT_HABITAT_2017=__DEP;
_FROM_=__DEP;
DROP __DEP;
DROP __FLAG;
RUN ;
QUIT ;
/* Création du fichier de sorti final*/
PROC SQL;
CREATE TABLE MODELE_RESULTS As
SELECT IDCLI_CALCULE, IP_1
FROM PREDLogRegPredictions;
RUN;
QUIT;
ODS GRAPHICS OFF;
Probably from this:
DATA WORK.TMP0TempTableAddtnlPredictData;
SET WORK.APPEND_TABLE(IN=__ORIG) WORK.BASE_PREDICT_2;
__FLAG=__ORIG;
__DEP=TOP_CREDIT_HABITAT_2017;
if not __FLAG then TOP_CREDIT_HABITAT_2017=.;
RUN;
You're appending a dataset that does not have a replicate number on it here. I'm not really sure I follow what this dataset is - are you intending this to be added to each replicate perhaps? Then you might do something like this (untested):
DATA WORK.TMP0TempTableAddtnlPredictData;
do _n_ = 1 by 1 until (eof);
SET WORK.APPEND_TABLE(IN=__ORIG) end=eof;
output;
end;
do replicate = 1 to 5;
do n_predict = 1 to nobs_predict;
set WORK.BASE_PREDICT_2 nobs=nobs_predict point=n_predict;
__FLAG=__ORIG;
__DEP=TOP_CREDIT_HABITAT_2017;
if not __FLAG then TOP_CREDIT_HABITAT_2017=.;
output;
end;
end;
stop;
RUN;
This is the complicated way to get 5 copies of that, one for each replicate. But I'm not sure that's actually what you want - does it even have all of the variables you need? Are you sure you didn't mean to MERGE instead of SET?
Separately, I don't understand why you use the SQL step to append the two samples. I'd either do that in the same data step here or I'd use PROC APPEND, both would be faster than the SQL union and then immediately appending more to the dataset.

SAS boxplot with inner margin

I'm not very experienced in SAS yet.
My problem is that I need to add number of observations to a boxplot (I'm using proc boxplot). I tried insetgroup option, but I don't like the result, I need something prettier.
I have found this
http://support.sas.com/resources/papers/wusspaper.pdf
I need something like this, with numbers in the inner margin
It's great they have code there, but I don't get where are these numbers (No. of subjects at visit) are taken from, if they are calculated separately, where they are in a dataset, etc. It's a pity the initial dataset is not shown.
Any help and any other ideas how to add numbers of patients will be very appreciated.
Below is some SAS code where the Ns are added to proc boxplot using annotate. In general for annotate, you need to be careful about setting up the coordinate system you want, read the documentation regarding annotate and xsys/ysys for a detailed explaination.
Hope this helps.
proc sort data=sashelp.class out=work.class;
by sex;
run;
*** GET COUNTS FOR EACH GROUP ***;
proc freq data=class;
tables sex / out=stats;
run;
*** CREATE ANNOTATE DATASET ***;
data anno_stats;
set stats (drop=percent);
xsys='2';
ysys='1';
position='5';
function='label';
text='N=' || strip( put(count, 3.));
*** X COORDINATE IS THE GROUP VARIBLE IN THE BOXPLOT ***;
*** USE VARIABLE XC INSTEAD OF X SINCE THIS IS A CHARACTER VARIABLE IN THIS EXAMPLE ***;
xc=sex;
*** Y COORDIANTE IS 3% ABOVE X-AXIS, BASED ON YSYS=1 ***;
y=3;
run;
proc boxplot data=class anno=anno_stats;
plot height * sex;
run;

How to create by group in proc gplot

I want to create multiple plots by category. Currently my code is as follows:
proc gplot data=data;
plot (a b)*week
*by category;
/vaxis=axis3 haxis=axis3 legend=legend1 overlay skipmiss;
title font='HELVETICA' height=1.2 "Volumes";
run;
but this includes all the categories. How do I create distinct charts for different categories? Also the chart here is a scatter plot. How do I create a line chart?
A fellow SAS 9.1.x user? Assuming that you require a gplot-based example:
proc summary data = sashelp.class nway;
var height;
class sex age;
output out = class mean=;
run;
symbol1 interpol = join;
proc gplot data = class;
by sex;
plot height * age;
run;
quit;
Here proc summary conveniently produces a sorted output dataset without any duplicate y-values, allowing gplot to produce a pair of reasonable line charts via the by statement. I'm sure there are much nicer-looking alternatives via proc sgplot if you have a more recent version of SAS, but some of us have to make do with gplot.

How to construct histograms with unequal class widths in SAS?

I am trying to create histograms in sas with the help of proc univariate in sas. But it gives me histograms with equal class widths. Suppose i want to have a histogram with first class interval from 1 to 10 and second class interval from 10 to 100.
I tried using-
proc univariate data=sasdata1.dataone;
var sum;
histogram sum/ midpoints=0 to 10 by 10 10 to 100 by 90 ;run;
But this does not work. What is the correct way of doing this?
You can't do it with UNIVARIATE as far as I know, but any of the SGPLOT/GPLOT/etc. procedures will work; just bin your data into a categorical variable and VBAR that variable.
If you're okay with frequencies (not percents), this would work:
data test;
set sashelp.class;
do _t = 1 to floor(ranuni(7)*20);
age=age+floor(ranuni(7)*10);
output;
end;
run;
proc format;
value agerange
low-12 = "Pre-Teen"
13-14 = "Early Teen"
15-18 = "Teen"
19-21 = "Young Adult"
22-high = "Adult";
quit;
ods graphics on;
ods preferences;
proc sgplot data=test;
format age agerange.;
vbar age;
run;
I believe if you need percents, you'd want to PROC FREQ or TABULATE your data first and then SGPLOT (or GPLOT) the results.
I did find a macro that can be used to create histograms with unequal endpoints.
The code can be found in the NESUG 2008 proceedings