I am using the function ggpredict to display a lmer model's result.
The model has a continuous X (RT), one continuous Y (RC1) and 4 discrete factors (2x2x2x14).
Model:
SailorJupiter <- lmer(RT~RC1*m2*m3*m5*m4 + (1|Trial:sonTrial) + (1|Subject) + (1|Trial) + (1|sonleft) + (1|sonright), data=audiostim, REML=FALSE)
library(see)
library(ggeffects)
a <- ggpredict(SailorJupiter, c("RC1","m2","m3","m4","m5"), dependencies=TRUE)
plot(a)
Example of plot without the 14-levels factor because it's too big
Question 1:
I'd like to have results with groups being a combination of m3 and m4 in order to simplify the graphs. I tried :
a <- ggpredict(SailorJupiter, c("RC1","m2","m3:m4","m5"), dependencies=TRUE)
plot(a)
But it doesn't work.
Question 2: Is there a way to use only one level of a factor in order to simplify the plot ? I know some other plotting packages allow it, but can't find it in ggpredict().
Related
I'm using the plot_model() function in R to visualize an interaction for an OLS regression.
The regression is:
model <- lm(dv ~ condition + control1 + control2 + variable1 + condition*variable1, data=data)
condition is a 4-level factor variable.
variable1 is a continuous variable.
control1 is a continuous variable.
control2 is a factor variable with 2-levels.
I'm trying to visualize the interaction of this regression, with variable1 on the x-axis, and condition as indicators.
However, I'm hoping to visualize it as if variable 1 was a factor variable, i.e., only showing particular points (2, 4, and 6) on the plot, with confidence interval whiskers, instead of a straight line across all continuous values and confindence interval bands around the line. So something that looks like this:
Rather than this:
I've tried multiple things but am having trouble looking for the right solution. Any help will be appreciated! The code I have now that creates the line & band plot is:
plot_model(model, type="pred",terms=c("variable1","condition"), ci.lvl=0.95)
Specify the points your want in brackets in the terms argument:
library(sjPlot)
model <- lm(hwy ~ year + drv * displ, data = ggplot2::mpg)
plot_model(model, type = "pred", terms = c("drv", "displ [2, 3, 5]"))
I'm trying to plot the predictions (predict()) of my mixed model below such that I can obtain my conceptually desired plot as a line below.
I have tried to plot my model's predictions, but I don't achieve my desired plot. Is there a better way to define predict() so I can achieve my desired plot?
library(lme4)
dat3 <- read.csv('https://raw.githubusercontent.com/rnorouzian/e/master/dat3.csv')
m4 <- lmer(math~pc1+pc2+discon+(pc1+pc2+discon|id), data=dat3)
newdata <- with(dat3, expand.grid(pc1=unique(pc1), pc2=unique(pc2), discon=unique(discon)))
y <- predict(m4, newdata=newdata, re.form=NA)
plot(newdata$pc1+newdata$pc2, y)
More sjPlot. See the parameter grid to wrap several predictors in one plot.
library(lme4)
library(sjPlot)
library(patchwork)
dat3 <- read.csv('https://raw.githubusercontent.com/rnorouzian/e/master/dat3.csv')
m4 <- lmer(math~pc1+pc2+discon+(pc1+pc2+discon|id), data=dat3) # Does not converge
m4 <- lmer(math~pc1+pc2+discon+(1|id), data=dat3) # Converges
# To remove discon
a <- plot_model(m4,type = 'pred')[[1]]
b <- plot_model(m4,type = 'pred',title = '')[[2]]
a + b
Edit 1: I had some trouble removing the dropcon term within the sjPlot framework. I gave up and fell back on patchwork. I'm sure Daniel could knows the correct way.
As Magnus Nordmo suggest, this is very simple with sjPlot which has some predefined functions for these types of plot.
library(lme4)
dat3 <- read.csv('https://raw.githubusercontent.com/rnorouzian/e/master/dat3.csv')
m4 <- lmer(math~pc1+pc2+discon+(pc1+pc2+discon|id), data=dat3)
plot_model(m4, type = 'pred', terms = c('pc1', 'pc2'),
ci.lvl = 0)
which gives the following result.
This plot is designed to include different quantiles of the second term in terms over the axes of pc1 and pred. You could split up these plots and combine them using patchwork and the interval can be changed by using square brackets after the term in terms (eg pc1 [-10:1] for interval between -10 and 1).
I have a multinomial logistic regression model built using multinom() function from nnet package in R. I have a 7 class target variable and I want to plot the coefficients that the variables included in the model have for each class of my dependent variable.
For a binary logistic regression I used coefplot() function from arm package, but I don't know how to do this for a multiclass problem.
I want my plots to look like this:
I couldn't easily find a sensible multinom() example: the one below gives ridiculous values, but the structure of the code should work anyway. The basic idea is to use broom::tidy() to extract coefficients and ggplot/ggstance to plot them. ggstance is specifically for plotting horizontal point-ranges and displacing them from each other an appropriate amount; this can also be done via coord_flip(), but coord_flip() induces a certain lack of flexibility (e.g. it can't easily be combined with faceting).
library(nnet)
library(broom)
library(ggplot2); theme_set(theme_bw())
library(ggstance)
Create example multinom() fit:
nvars <- c("mpg","disp","hp")
mtcars_sc <- mtcars
mtcars[nvars] <- scale(mtcars[nvars])
m <- multinom(cyl~mpg+hp+disp,mtcars_sc,
maxit=1e4)
Extract coefficients and drop intercept terms:
tt <- broom::tidy(m,conf.int=TRUE)
tt <- dplyr::filter(tt, term!="(Intercept)")
Plot:
ggplot(tt, aes(x=estimate,y=term,colour=y.level))+
geom_pointrangeh(aes(xmin=conf.low,
xmax=conf.high),
position=position_dodgev(height=0.75))
Given that you're able to get your data like this:
coeff <- factor(1:7,labels=c("inc", "lwg", "hcyes", "wcyes","age", "k618", "k5"))
values <- c(-0.1,0.6,0.15,0.8,-0.05,-0.05,-1.5)
upper <- c(-0.1,1,.6,1.3,-.05,.1,-1)
lower <- c(-0.1,.2,-.2,.3,-.05,-.2,-2)
df <- data.frame(coeff,values,upper,lower)
Then all you have to do is run:
library(ggplot2)
ggplot(df, aes(x=coeff, y=values, ymin=lower, ymax=upper)) +
geom_pointrange() +
geom_hline(yintercept=0, linetype=2)+
coord_flip()
The result should look like this:
You can experiment with certain options to get it to look identical to your example
I would like to reproduce lmer diagnostic plots in ggplot2. Particularly, I know that for a lmer model DV ~ Factor1 * Factor2 + (1|SubjID) I can simply call plot(model, resid(.)~fitted(.)|Factor1+Factor2) to generate a lattice-based Residuals Vs. Fitted plot, faceted for each Factor1+Factor 2 combination.
I would like to generate the same plot, but using ggplot2. I tried using qplot(resid(model), fitted(model)) and different variations of that with different arguments, but the information about the factors needed for faceting is not coming through with this (and similar) calls.
I'd appreciate any advise to achieve this, thanks!
EDIT
The core of my question: given any lmer model, how can I create a data-frame including fitted and residual values AND the Factor information for each value? something like:
Factor1 Factor2 Fitted Resid
0 0 987 654
0 0 123 456
(...)
I could not figure that out from lmer documentation on the resid() and fitted() functions
Here is an example of what we want, a reproducible example
data(Orthodont, package="nlme")
Orthodont$age <- as.factor(Orthodont$age)
model <- lmer(distance ~ age * Sex + (1|Subject), Orthodont)
plot(model, resid(.) ~ fitted(.) | age + Sex )
answer
ggplot(model, aes(.fitted, .resid)) + geom_point() +
facet_wrap(~ Sex + age, ncol = 4) # (edited) I noticed fortify(model) isn't necessary.
I want to make a random effects plot using the plot method for ranef objects (plot.ranef.lme).
library(nlme)
x <- Orthodont
# change factor to unordered for this example
x$Subject <- factor(x$Subject, ordered=FALSE)
m <- lme(distance ~ age, x, random = ~ 1 | Subject)
re <- ranef(m)
plot(re)
Above, the order of the factor on the y-axis follows the order of the factor levels.
Now, I want the order of the levels to correspond to the size of the random effect parameters. The best I could come up with is to reorder the factor levels by using the random effects parameters after estimating the model, reorder the factor and estimate the model again. This is clumsy to say the least, but I was unable to get this done via some arguments in the plot method (I am not very familiar with lattice).
o <- order(re[, 1])
x$Subject <- factor(x$Subject, levels=levels(x$Subject)[o])
m <- lme(distance ~ age, x, random = ~ 1 | Subject)
re <- ranef(m)
plot(re)
This is what I want but without using the clumsy approach above.
How can I do this in a more sensible way?
I don't think teher is a parameter that can be used to change order levels. You should do it by hand .
That's said you can plot your own dotplot using the re object, and use reorder to order factor.
library(lattice)
dat = data.frame(x= row.names(re),y=re[,attr(re,'effectName')])
dotplot(reorder(x,y)~y,data=dat)