Apologies for that. Here's my question with a reproducible data set:
library(effects)
data(Arrests)
Arrests$year <- as.factor(Arrests$year)
arrests.mod <- glm(released ~ employed + citizen + checks + colour*year +
colour*age, family=binomial, data=Arrests)
t.effects <- allEffects(arrests.mod)
plot(t.effects, "colour:year")
plot(t.effects, "colour:age")
Is it possible to combine the two plots into a single figure?
par(mfrow=c(2,1))
This doesn't work. I.e. the figures are reproduced separately in two graphs, but not in the same figure.
par(mfrow=c(2,1)) don't work for grid plots. It is only for base graphics. You can use gridExtra to arrange lattice plots.
library(gridExtra)
p1 <- plot(t.effects, "colour:year")
p2 <- plot(t.effects, "colour:age")
grid.arrange(latticeGrob(p1),
latticeGrob(p2))
You can reference specific effects from your alleffects object with vector indices. In your case I believe t.effects[4:5] or, equivalently, t.effects[c("colour:year", "colour:age")]
library(effects)
data(Arrests)
Arrests$year <- as.factor(Arrests$year)
arrests.mod <- glm(released ~ employed + citizen + checks + colour*year + colour*age, family=binomial, data=Arrests)
t.effects <- allEffects(arrests.mod)
plot(t.effects[4:5])
Related
I am trying to replicate this plot, here:
Here is the source of this plot, slide 89:
http://www.drizopoulos.com/courses/Int/JMwithR_CEN-ISBS_2017.pdf
The top of the plot is the hazard function over time, whereas the bottom green curve is the fitted linear mixed effects model over time.
I have been able to plot both of these separately, however, cannot seem to combine them using either par(mfrow=c(2,1)) or the gridExtra package (because only one is a ggplot object).
I am using the aids and aids.id datasets (as a part of the JM package) in R.
# Load packages JM and lattice
library("JM")
library("lattice")
library("ggplot2")
#Fit models
lmeFit.aids <- lme(CD4 ~ obstime + obstime:drug,
random = ~ obstime | patient, data = aids)
coxFit.aids <- coxph(Surv(Time, death) ~ drug, data = aids.id, x = TRUE)
#Plot longitudinal process
p1<-ggplot(data=aids,aes(x=obstime,y=fitted(lmeFit.aids)))
p1<-p1+geom_smooth(se=FALSE)
p1
#Plot survival process
library(rms)
p2<-psm(Surv(Time,death)~1,data=aids.id)
survplot(p2,what='hazard')
Thank you!
Up front, patchwork allows you to combine ggplot2 and base graphics into one plot. Adapted from ?wrap_elements,
library(ggplot2)
library(patchwork)
gg <- ggplot(mtcars, aes(mpg, disp)) + geom_point()
gg / wrap_elements(full = ~ plot(mtcars$mpg, mtcars$disp))
I was able to extract the values of the hazard at various time points using the survest() function. Then, I was able to plot this using ggplot, meaning I could use grid.arrange().
est<-survest(p2,,what='hazard')
hazard<-data.frame(time=est$time, hazard=est$surv)
I would like to combine continuous and quantile models in the same plot to compare and contrast the two approaches (xtile is a function that returns the quantile as factor):
q.s <- cph(inc ~ rcs(exposure,3), data=data)
q.q <- cph(inc ~ xtile(exposure,3), data=data)
p.s <- Predict(q.s, exposure, fun=exp)
p.q <- Predict(q.q, exposure, fun=exp)
ggplot.Predict gives a nice plot of either model - but I would like to combine both. Is this possible?
I have added an example - which I hope might illustrate what I would like to generate.
enter image description here
Try this where plot1/2 are your quantile and continuous plots (can change heights, widths, number of columns, number of rows):
p1 <- ggplot.Predict(..plot1 options here...)
p2 <- ggplot.Predict(..plot2 options here...)
library(gridExtra)
grid.arrange(p1, p2,
ncol=2, nrow=1, widths=c(2,2), heights=c(2))
For more information, check out the gridExtra package.
I have a dataset of leaf trait measurements made at multiple sites at two contrasting seasons. I am interested to explore the association/line fit between a pair of traits and to differentiate the seasons at each site.
Rather than a linear regression, I would prefer to use the Standardised Major Axis approach within the smatr package:
e.g. sma.site1 <- sma(TraitA ~ TraitB * Visit, data=subset(myfile, Site=="Site1")) # testing the null hypothesis of common slopes for the two Visits (Seasons) at a given Site.
I can produce a handy lattice plot in ggplot2 with a separate panel for each Site and the points differentiated by Visit:
e.g. qplot(TraitB, TraitA, data=myfile, colour=Visit) + facet_wrap(~Site, ncol=2)
However, if I add trend lines fitted with the additional argument in ggplot2:
+ geom_smooth(aes(group=Visit), method="lm", se=F)
……, those lines are not a good match for the sma coefficients.
What I would like to do is fit the lines suggested by the sma test onto the ggplot lattice. Is there an easy, or efficient, way to do that?
I know that I can subset the data, produce a plot for each site, add the relevant lines with + geom_abline() and then stitch the separate plots up together with grid.arrange(). But that feels very long-winded.
I would be grateful for any pointers.
I don't know anything about the smatr package but you should be able to tweak this to get the right values. Since you provided no data I used the leaf data from the example in the pkg. The basic idea is to pull out the slope & intercept from the returned sma object and then facet the geom_abline. I may be misinterpreting the object, though.
library(smatr)
library(ggplot2)
data(leaflife)
do.call(rbind, lapply(unique(leaflife$site), function(x) {
obj <- sma(longev~lma*rain, data=subset(leaflife, site=x))
data.frame(site=x,
intercept=obj$coef[[1]][1, 1],
slope=obj$coef[[1]][2, 1])
})) -> fits
gg <- ggplot(leaflife)
gg <- gg + geom_point(aes(x=lma, y=longev, color=soilp))
gg <- gg + geom_abline(data=fits, aes(slope=slope, intercept=intercept))
gg <- gg + facet_wrap(~site, ncol=2)
gg
I just saw this question and am not sure if you are still interested in this. I run the code by hrbrmstr, and found actually the only thing you need to change is:
obj <- sma(longev~lma*rain, data=subset(leaflife, site == x))
then you can get the plot with four lines for each group.
and also
This is the basic example given in the iNEXT package:
library(iNEXT)
data(spider)
# multiple abundance-based data with multiple order q
z <- iNEXT(spider, q=c(0,1,2), datatype="abundance")
p1 <- ggiNEXT(z, facet.var="site", color.var="order")
In my dataset, i have more samples and the facetting does not work so great:
, so i want to change the ncol/nrow arguments in the facet_wrap/grid-call inside the object "p1". p1 is a ggplot object, so it can be altered (f.e. p1 + xlab("") removes the x-title).
In general, it would be nice to know how gginext() can be decomposed into single lines, and what objects are used in the data arguments, so i can change the order of the samples and reduce the amount of samples used per plot. Somehow, i wasnt able to find that out by looking at the function itself, also i get "Error: ggplot2 doesn't know how to deal with data of class iNEXT" when i try to follow gginext() step-by-step.
You could use facet_wrap(~site, ncol=3) to tune your plot. Take a simple example as following:
library(iNEXT)
library(ggplot2)
set.seed(123)
p <- 1/1:sample(1:50, 1)
p <- p/sum(p)
dat <- as.data.frame(rmultinom(9, 200, p))
z <- iNEXT(dat, q=c(0,1,2))
p1 <- ggiNEXT(z, facet.var="site", color.var="order")
p1 + facet_wrap(~site, ncol=3)
I would like to plot an INDIVIDUAL box plot for each unrelated column in a data frame. I thought I was on the right track with boxplot.matrix from the sfsmsic package, but it seems to do the same as boxplot(as.matrix(plotdata) which is to plot everything in a shared boxplot with a shared scale on the axis. I want (say) 5 individual plots.
I could do this by hand like:
par(mfrow=c(2,2))
boxplot(data$var1
boxplot(data$var2)
boxplot(data$var3)
boxplot(data$var4)
But there must be a way to use the data frame columns?
EDIT: I used iterations, see my answer.
You could use the reshape package to simplify things
data <- data.frame(v1=rnorm(100),v2=rnorm(100),v3=rnorm(100), v4=rnorm(100))
library(reshape)
meltData <- melt(data)
boxplot(data=meltData, value~variable)
or even then use ggplot2 package to make things nicer
library(ggplot2)
p <- ggplot(meltData, aes(factor(variable), value))
p + geom_boxplot() + facet_wrap(~variable, scale="free")
From ?boxplot we see that we have the option to pass multiple vectors of data as elements of a list, and we will get multiple boxplots, one for each vector in our list.
So all we need to do is convert the columns of our matrix to a list:
m <- matrix(1:25,5,5)
boxplot(x = as.list(as.data.frame(m)))
If you really want separate panels each with a single boxplot (although, frankly, I don't see why you would want to do that), I would instead turn to ggplot and faceting:
m1 <- melt(as.data.frame(m))
library(ggplot2)
ggplot(m1,aes(x = variable,y = value)) + facet_wrap(~variable) + geom_boxplot()
I used iteration to do this. I think perhaps I wasn't clear in the original question. Thanks for the responses none the less.
par(mfrow=c(2,5))
for (i in 1:length(plotdata)) {
boxplot(plotdata[,i], main=names(plotdata[i]), type="l")
}