I'm wondering if there's a way to add an inset graph in another graph in SAS. I see quite a bit of stuff about adding text insets into a figure, but nothing about a graph. I am making scatterplots with, for example, leaf mass on the x-axis, and leaf area on the y. The slope of the line tells me the ratio of these two quantities, which is specific leaf area. This is also important, so I want to be able to show that, as well. But since its not new information (relative to the scatterplots), I don't want to make another figure since it will basically show the same thing, just in different ways. But if I had it as an inset, that would be okay.
I use SAS 9.4 at school and SAS university edition at home. Here's the code I have for the scatterplot:
proc template; define statgraph Graph;
dynamic _MASS_PER_LEAF _SA_PER_LEAF _GROUP _LT_MASS_PER_LEAF _LT_SA_PER_LEAF _GROUP2;
begingraph / designwidth=500 designheight=819 attrpriority=none DataSymbols=(circle x circle x circle x) DataContrastColors=(CX0000FF CX0000FF CXCC0033 CXCC0033 CX639A21 CX639A21)
DataLinePatterns=(1 2 1 2 1 2);
legendItem type=marker name='Beech' / label = 'Beech' markerattrs=(color=CX0000FF symbol=circlefilled) ;
legendItem type=marker name='Red Maple' / label = 'Red Maple' markerattrs=(color=CXCC0033 symbol=circlefilled) ;
legendItem type=marker name='Sugar Maple' / label = 'Sugar Maple' markerattrs=(color=CX639A21 symbol=circlefilled) ;
legendItem type=marker name='Calcium' / label = 'Calcium' markerattrs=(color=black symbol=circle) ;
legendItem type=marker name='Control' / label = 'Control' markerattrs=(color=black symbol=x) ;
layout lattice / rowdatarange=data columndatarange=union rows=2 rowgutter=10 columngutter=10 rowweights=(1.0 1.0);
layout overlay / yaxisopts=( label=('Average surface area per leaf (cm^2)'));
scatterplot x=_MASS_PER_LEAF y=_SA_PER_LEAF / group=_GROUP name='scatter' markerattrs=(size=11 weight=bold );
regressionplot x = mass_per_leaf y = sa_per_leaf / group = group;
entry halign=left 'Green leaves' / valign=top;
endlayout;
layout overlay / yaxisopts=( label=('Averge surface area per leaf (cm^2)'));
scatterplot x=_LT_MASS_PER_LEAF y=_LT_SA_PER_LEAF / group=_GROUP2
name='scatter2' markerattrs=(size=11 weight=bold );
regressionplot x = mass_per_leaf y = sa_per_leaf / group = group;
entry halign=left 'Senesced leaves' / valign=top;
discretelegend 'Beech' 'Red Maple' 'Sugar Maple' 'Calcium' 'Control' /
opaque=false
border=true
halign=right
valign=bottom
displayclipped=true
down=3
order=columnmajor
location=inside;
endlayout;
columnaxes;
columnaxis / label=('Average mass per leaf (g)');
endcolumnaxes;
endlayout;
endgraph;
end;
run;
proc sgrender data=WORK.CALCIUM template=Graph;
dynamic _MASS_PER_LEAF="'MASS_PER_LEAF'n" _SA_PER_LEAF="'SA_PER_LEAF'n" _GROUP="GROUP" _LT_MASS_PER_LEAF="'LT_MASS_PER_LEAF'n" _LT_SA_PER_LEAF="'LT_SA_PER_LEAF'n" _GROUP2="GROUP";
run;
Thank you for any help!
Related
I want to use a slider in R Shiny to give the user control over the frequency a category is sampled from a data frame. The slider should have a default value of 0.5 (and range from 0 to 1), and at the default value (0.5), I have defined the frequency by which each category should be sampled. When the user adjusts the slider towards 1 (the maximum), I would like the frequencies of the highest categories to become even higher at the expense of the lowest frequency categories and vice-versa when the slider is adjusted towards 0 (the lowest frequency categories should increase, while the highest decrease). The frequencies should always sum to 1.
For example, I have a data frame that contains six categories and the frequencies by which each category is initially sampled. For instance:
df <- data.frame(food = c("fish", "shrimp", "chicken", "lamb", "beef", "tofu"), frequency = c(0.20, 0.06, 0.30, 0.10, 0.23, 0.11))
When the R Shiny slider is set to 1, I want the frequency of the initial highest category (chicken) to be 1.0, with the other categories being 0. As the slider goes to 1, I also want the next highest categories (beef and fish) to increase, but they should maintain the initial frequency order (with chicken remaining highest) until (as the slider gets closer to 1) they also go to 0 and chicken goes to 1.0. The highest categories (chicken, beef, and fish) should grow at the expense of the lowest categories (tofu, lamb, and shrimp), with shrimp (the lowest frequency) being the first to go to 0, followed by lamb and tofu.
I would like a similar (but opposite) process to occur as the slider goes to 0, with shrimp eventually being at a frequency of 1 (and lamb and tofu initially increasing at the expense of the higher frequency categories) and chicken being the first to go to 0 (followed by beef, fish, tofu, and lamb).
Essentially I need to rework the sample_data function in the example below:
library(shiny)
sample_data <- function(slider_value, data) {
adjusted_frequency <- data$frequency + (slider_value) * (max(data$frequency) - data$frequency)
data$sampled_frequency <- adjusted_frequency / sum(adjusted_frequency)
return(data)
}
ui <- fluidPage(
titlePanel("Input Data Using a Slider"),
sidebarLayout(
sidebarPanel(
sliderInput("value", "Enter a value:",
min = 0, max = 1, value = 0.5)
),
mainPanel(
tableOutput("data")
)
)
)
server <- function(input, output) {
df <- data.frame(food = c("fish", "shrimp", "chicken", "lamb", "beef", "tofu"), frequency = c(0.20, 0.06, 0.30, 0.10, 0.23, 0.11))
data <- reactive({
sample_data(input$value, df)
})
output$data <- renderTable({
data()
})
}
shinyApp(ui, server)
Right now, the slider I have gives the results as depicted in the image below:
When set to 0, it displays the default frequencies, and when set to 1 it has all categories at equal frequencies. How can I improve the sample_data function to accomplish the more complicated procedure I have described?
Thank you very much for your help!
I have a dataset in which I am graphing means from 4 treatments over time, along with their standard errors, at 2 sites. The standard error bars are not being assigned properly to their respective means --they are going to both panels - can you please advise? See example:
d <- data.frame(site=rep(1:2,each=12),time=rep(1:3,8),trt=rep(rep(1:4,each=3),2))
d$mn <- rnorm(24,4,1)
d$se <- rnorm(24,2,1)
d$ul <- d$mn+d$se # create y value for standard error upper limit
my.panel <- function(x,y, ...){
panel.xyplot(x, y, ...)
panel.arrows(x, y, x, d$ul, length = 0.1,
angle = 90)
}
xyplot(mn ~ time|site,data=d,
group = trt,
type=c('p','l'),
panel = my.panel
)
i'm using SAS 9.4 and created a nice bar-chart with sgpanel like this
enter image description here
The code is as follows:
proc sgpanel data=transp_5;
panelby position / layout=columnlattice onepanel
colheaderpos=bottom rows=2 novarname noborder;
styleattrs datacolours=(CXbe0a6e CXbe0a6e
CXe17d00 CXe17d00
CXbcc121 CXbcc121
CX3caf7f CX3caf7f
CX0077ad CX0077ad)
DATACONTRASTCOLORS=(nocolour);
format position order.;
format crop_type concatf.;
vbar crop_type / group=crop_type response=col1 stat=sum nostatlabel
barwidth=1 groupdisplay=cluster CLUSTERWIDTH= 1;
colaxis display=none;
rowaxis grid labelattrs =(size=12) valueattrs=(size=12)
label="probability" ;
keylegend / valueattrs=(size=10) titleattrs=(size=10) AUTOITEMSIZE
title="crop group" down=2;
where time in ("Feb01", "Jul02", "Aug01", "Sep01" ," Okt02" ,
"Nov01");
run;
Wat i want now, is to distinguish between the attributes "Ps" and "Pfw" for the crops (e.g. corn maize with the SAME colour) by using a fill pattern like dashed or something else.
I found the FILLPATTERNATTRS= options which should work with sgpanelm but it doesn't work so far.
How can i combine fill colours and fill patterns with sgpanel in SAS 9.4?
Thanks,
Sandra
I use SAS 9.4 and updated to M5 in order to use the fillpatterms, but it didn't work. BUT: i solved it, yeah! See the result here: enter image description here
i used a style template and modified it a little as follows
proc template;
define style Styles.meins;
parent = styles.Journal3;
style GraphData1 from GraphData1 /
fillpattern = "solid";
style GraphData2 from GraphData2 /
fillpattern = "L1";
style GraphData3 from GraphData3 /
fillpattern = "solid";
style GraphData4 from GraphData4 /
fillpattern = "L1";
style GraphData5 from GraphData5 /
fillpattern = "solid";
style GraphData6 from GraphData6 /
fillpattern = "L1";
style GraphData7 from GraphData7 /
fillpattern = "solid";
style GraphData8 from GraphData8 /
fillpattern = "L1";
style GraphData9 from GraphData9 /
fillpattern = "solid";
style GraphData10 from GraphData10 /
fillpattern = "L1";
style GraphData11 from GraphData11 /
fillpattern = "solid" ;
style GraphData12 from GraphData12 /
fillpattern = "L1" ;
style GraphData13 from GraphData13 /
fillpattern = "solid";
end;
run;
ods graphics on;
ods html path ='datasave_path'
image_dpi=500
style=meins; quit;
proc sgpanel data=zusammen;
panelby position/ layout=columnlattice onepanel
colheaderpos=top novarname noborder spacing=1;
styleattrs datacolors=(CXbe0a6e CXbe0a6e
CXe13f0d CXe13f0d
CXe17d00 CXe17d00
CXbcc121 CXbcc121
CX3caf7f CX3caf7f
CX0077ad CX0077ad
CXB2B2B2)
DATACONTRASTCOLORS=(black);
format position order.;
format crop_type concatf_a.;
vbar crop_type / group=crop_type response=col1 stat=sum nostatlabel
barwidth=1 groupdisplay=cluster
CLUSTERWIDTH=1;
colaxis display=none;
rowaxis grid labelattrs =(size=12) valueattrs=(size=12)
label="probability" GRID VALUES = (0 TO 1 BY 0.1);
keylegend / valueattrs=(size=10) titleattrs=(size=0) AUTOITEMSIZE
title="" down=4 noborder;
where time in ("Feb01", "Feb02" , "Mar01" , "Mar02" , "Apr01" );
run;
I didn't trie the attribute map, but this would have been the next step if the style template wouldn't have been working.
Thanks,
Sandra
I'm trying to get markers to show up on my chart using the Graphics Template Language. I've tried adding the marker definitions to the style, to the seriesplot statement within a markerattrs= option statement, and also using discreteattrmaps for the chart group. I can't seem to get any of these approaches working.
Style definition:
proc template;
define style excel;
parent=styles.htmlblue;
class graph / attrpriority='none';
style graphdata1 / contrastColor=#416FA6;
style graphdata2 / contrastColor=#A8423F;
style graphdata3 / contrastColor=#86A44A;
style graphdata4 / contrastColor=#8064A2;
style graphdata5 / contrastColor=#DA8137;
style graphdata6 / contrastColor=#D7E4BD;
style graphdata7 / contrastColor=#FCD5B5;
style graphdata8 / contrastColor=#8EA5CB;
style graphdata9 / contrastColor=#E6B9B8;
style graphdata10 / contrastColor=#CCC1DA;
end;
run;
Template for the chart:
proc template;
define statgraph excel_series_trended;
dynamic _date _class _metric _title;
begingraph;
entrytitle halign=center _title;
discreteattrmap name="symbols" / ignorecase=true ;
value "IBM" / markerattrs=(color=blue symbol=diamondfilled) ;
value other / markerattrs=(color=red symbol=circlefilled) ;
enddiscreteattrmap ;
discreteattrvar attrvar=groupmarkers var=stock attrmap="symbols" ;
layout lattice / rowdatarange=data columndatarange=data rowgutter=0 columngutter=0;
layout overlay / walldisplay=(fill)
yaxisopts=( griddisplay=on gridattrs=(pattern=2 color=Cx999999) linearopts=(viewmin=0) )
xaxisopts=( type=discrete );
seriesplot x=_date y=_metric / group=_class markercolorgroup=_class name='series' groupdisplay=overlay connectorder=xaxis lineattrs=(pattern=solid thickness=3);
endlayout;
sidebar / align=bottom spacefill=false;
discretelegend 'series' / opaque=true border=false halign=center valign=center displayclipped=true order=rowmajor;
endsidebar;
endlayout;
endgraph;
end;
run;
Render the chart using the sashelp.stocks dataset:
ods html style=excel;
ods graphics / antialias=on antialiasmax=999999;
proc sgrender data=sashelp.stocks template=excel_series_trended;
where date between '01jan2005'd and '01jun2005'd;
dynamic _date="date" _metric="high" _class="stock";
run;
You need to do two things, presumably.
First, add display=(markers) to the seriesplot statement; that enables markers.
Second, add markersymbolgroup=groupmarkers to that same statement to enable the discrete attribute map to be used for markers, and change markercolorgroup to the same value. You cannot use a dynamic variable to define these, and shouldn't - you should use the discreteattrvar value.
Full code:
proc template;
define statgraph excel_series_trended;
dynamic _date _class _metric _title;
begingraph;
entrytitle halign=center _title;
discreteattrmap name="symbols" / ignorecase=true ;
value "IBM" / markerattrs=(color=blue symbol=diamondfilled) ;
value other / markerattrs=(color=red symbol=circlefilled) ;
enddiscreteattrmap ;
discreteattrvar attrvar=groupmarkers var=stock attrmap="symbols" ;
layout lattice / rowdatarange=data columndatarange=data rowgutter=0 columngutter=0;
layout overlay / walldisplay=(fill)
yaxisopts=( griddisplay=on gridattrs=(pattern=2 color=Cx999999) linearopts=(viewmin=0) )
xaxisopts=( type=discrete );
seriesplot x=_date y=_metric / group=_class name='series'
markersymbolgroup=groupmarkers markercolorgroup=groupmarkers
groupdisplay=overlay connectorder=xaxis lineattrs=(pattern=solid thickness=3)
display=(markers);
endlayout;
sidebar / align=bottom spacefill=false;
discretelegend 'series' / opaque=true border=false halign=center valign=center displayclipped=true order=rowmajor;
endsidebar;
endlayout;
endgraph;
end;
run;
Although I've marked Joe's answer as accepted I ended up choosing a slightly different solution that was easier to maintain in my final project.
The key part of the syntax I was missing was the display=(markers) option on seriesplot (as Joe pointed out). Once that was added, I was able to control the marker symbol simply by specifying it in the style:
proc template;
define style excel;
parent=styles.htmlblue;
class graph / attrpriority='none';
style graphdata1 / contrastColor=#416FA6 markersymbol='circlefilled';
style graphdata2 / contrastColor=#A8423F markersymbol='circlefilled';
style graphdata3 / contrastColor=#86A44A markersymbol='circlefilled';
end;
run;
Unfortunately the style does not support the markersize= option (despite what the documentation says). For that I ended up adding the markerattrs=(size=_markersize) option to the seriesplot statement. I made _markersize a dynamic value with a default of 0px, (ie. don't show markers). Now the template allows me to easily change the symbol, and or the size of the markers:
proc template;
define statgraph excel_series_trended;
dynamic _date _class _metric _title _markersize=0px;
begingraph;
entrytitle halign=center _title;
layout lattice / rowdatarange=data columndatarange=data rowgutter=0 columngutter=0;
layout overlay / walldisplay=(fill)
yaxisopts=( griddisplay=on gridattrs=(pattern=2 color=Cx999999) linearopts=(viewmin=0) )
xaxisopts=( type=discrete );
seriesplot x=_date y=_metric / display=(markers) group=_class name='series' groupdisplay=overlay connectorder=xaxis
lineattrs=(pattern=solid thickness=3)
markerattrs=(size=_markersize)
;
endlayout;
sidebar / align=bottom spacefill=false;
discretelegend 'series' / opaque=true border=false halign=center valign=center displayclipped=true order=rowmajor;
endsidebar;
endlayout;
endgraph;
end;
run;
Disclaimer: I am an amateur programmer. I am a student.
So I've been working on a Van Westendorf price model which requires analysis of critical points produced when the kernel density lines overlayed on 4 histograms intersect. My current model has 3 histograms, so 3 lines, and 2 intersections. How can I label these intersections?
You can see the output here.
http://i.imgur.com/6TGWv4l.jpg
Here is the code:
Proc Import Out = work.SASdata datafile =
"C:\Users\jdelizza\Desktop\SimpleSAS.xls"
DBMS = xls;
Sheet = "Asthma";
Getnames = yes;
Label I_Price_A = 'Too Expensive'
I_Price_B = 'Inexpensive'
I_Price_C = 'Slightly Expensive'
F_Price_Low = 'Full Price Inexpensive'
F_Price_Expensive = 'Full price Expensive'
F_Price_Too_Expensive = 'Full Price Too Expensive'
P_Price_Low = 'Personalized Price Inexpensive'
P_Price_Expensive = 'Personalized price Expensive'
P_Price_Too_Expensive= 'Personalized Price Too Expensive';
run;
proc sgplot;
Title "Those with Asthma Indoor Pricing";
histogram I_Price_A / fillattrs=graphdata1 transparency = .5 binstart =1
binwidth=50;
density I_Price_A /type = kernel lineattrs=graphdata1;
histogram I_Price_B / fillattrs=graphdata2 transparency=.5 binstart=1
binwidth=50;
density I_Price_B /type = kernel lineattrs=graphdata2;
histogram I_Price_C / fillattrs=graphdata3 transparency=.5 binstart=1
binwidth=50;
density I_Price_C / type = kernel lineattrs=graphdata3;
keylegend / location=inside position=topright noborder across=2;
yaxis grid;
xaxis display=(nolabel) values=(0 to 1000 by 100);
run;