combine two plots into one plot in a mixed-model plot

早过忘川 提交于 2021-02-08 06:40:55

问题


In my plot below, d_math and d_hyp are each {0,1} variables. Given this fact, in my plot below, I was wondering if we can combine the two plots into one, just like in the desired plot further below?

ps. I'm open to any R packages.

multivariate <- read.csv('https://raw.githubusercontent.com/hkil/m/master/bv.csv')

library(nlme)
library(effects) # for plot

m2 <- lme(var ~ 0 + d_math + d_hyp + d_math:I(grade-2) + d_hyp:I(grade-2),
          random = ~ 0 + d_math + d_hyp + d_math:I(grade-2) + d_hyp:I(grade-2) | id, data = multivariate,
          na.action = na.omit, weights = varIdent(c(hyp=.3), form = ~1|grp),
          control = lmeControl(maxIter = 200, msMaxIter = 200, niterEM = 50,
                               msMaxEval = 400))

plot(allEffects(m2), multiline = TRUE, x.var="grade")

Desired:


回答1:


We could use tidyverse to create a single plot. Loop over the list of allEffects output with imap, convert to tibble, select the columns needed, row bind the list elements to single dataset (_dfr), unite two columns to a single, and use ggplot for plotting

library(dplyr)
library(tidyr)
library(purrr)
library(ggplot2)
imap_dfr(allEffects(m2), ~ as_tibble(.x) %>% 
     mutate(dname = grep("d_", names(.), value = TRUE)) %>%
     select(dname, dvalue = starts_with('d_'), grade, fit) %>%
     mutate(grp = .y)) %>%
   unite(dname, dname, dvalue, sep=" = ") %>% 
   ggplot(aes(x = grade, y = fit, color = dname)) +
        geom_line() +
        theme_bw() #+
        # facet_wrap(~ grp)

-output


If we want the labels at the end of line, use directlabels

library(directlabels)
imap_dfr(allEffects(m2), ~ as_tibble(.x) %>% 
     mutate(dname = grep("d_", names(.), value = TRUE)) %>%
     select(dname, dvalue = starts_with('d_'), grade, fit) %>%
     mutate(grp = .y)) %>%
   unite(dname, dname, dvalue, sep=" = ") %>% 
   ggplot(aes(x = grade, y = fit, group = dname, color = dname)) +
        geom_line() +
        theme_bw() +
        scale_colour_discrete(guide = 'none') +
        geom_dl(aes(label = dname), method="last.qp", cex = 0.8)

Also, this can be done for each 'dvalue' as a facet

imap_dfr(allEffects(m2), ~ as_tibble(.x) %>% 
     mutate(dname = grep("d_", names(.), value = TRUE)) %>%
     select(dname, dvalue = starts_with('d_'), grade, fit) %>%
     mutate(grp = .y)) %>%
   unite(dname, dname, dvalue, sep=" = ", remove = FALSE) %>% 
   ggplot(aes(x = grade, y = fit, group = dname, color = dname)) +
        geom_line() +
        theme_bw() +
        scale_colour_discrete(guide = 'none') +
        geom_dl(aes(label = dname), method="last.qp", cex = 0.8) + 
        facet_wrap(~ dvalue)


Or if we need only a specific level, then filter

imap_dfr(allEffects(m2), ~ as_tibble(.x) %>% 
     mutate(dname = grep("d_", names(.), value = TRUE)) %>%
     select(dname, dvalue = starts_with('d_'), grade, fit) %>%
     mutate(grp = .y)) %>%
   unite(dname, dname, dvalue, sep=" = ") %>%
   filter(dname  %in% c("d_hyp = 1", "d_math = 1")) %>% 
   ggplot(., aes(x = grade, y = fit, colour = dname, group = dname)) + 
     geom_line() + 
     scale_colour_discrete(guide = 'none') +  
     geom_dl(aes(label = dname), method="last.qp", cex = 0.6) + 
     theme_bw()




回答2:


You could do it like this with lattice and a bit more brute force than @akrun's approach:

e <- allEffects(m2)

f1 <- matrix(e[[1]]$fit, ncol=5) # math
f2 <- matrix(e[[2]]$fit, ncol=5) # hyp

dat = data.frame(
  fit = c(f1[5,], f2[5,]), 
  grade = rep(c(2,4,5,6,8), 2), 
  variable = factor(rep(1:2, each=5), 
                    labels=c("Math=1", "Hyp=1"))
  )


xyplot(fit ~ grade, data=dat, group=variable, type="l", 
       auto.key=list(space="top", lines=TRUE,points=FALSE))



来源:https://stackoverflow.com/questions/65862745/combine-two-plots-into-one-plot-in-a-mixed-model-plot

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!