How to display different levels in a multilevel an

2019-06-24 15:03发布

问题:

I am a beginner at multilevel analysis and try to understand how I can do graphs with the plot functions from base-R. I understand the output of fit below but I am struggeling with the visualization. df is just some simple test data:

t <- seq(0, 10, 1)
df <- data.frame(t = t,
                 y = 1.5+0.5*(-1)^t + (1.5+0.5*(-1)^t) * t,
                 p1 = as.factor(rep(c("p1", "p2"), 10)[1:11]))

fit <- lm(y ~ t * p1, data = df)

# I am looking for an automated version of that:
plot(df$t, df$y)
lines(df$t[df$p1 == "p1"], 
      fit$coefficients[1] + fit$coefficients[2] * df$t[df$p1 == "p1"], col = "blue")
lines(df$t[df$p1 == "p2"], 
      fit$coefficients[1] + fit$coefficients[2] * df$t[df$p1 == "p2"] + 
        + fit$coefficients[3] + fit$coefficients[4] * df$t[df$p1 == "p2"], col = "red")

It should know that it has to include p1 and that there are two lines.
The result should look like this:

Edit: Predict est <- predict(fit, newx = t) gives the same result as fit but still I don't know "how to cluster".

Edit 2 @Keith: The formula y ~ t * p1 reads y = (a + c * p1) + (b + d * p1) * t. For the "first blue line" c, d are both zero.

回答1:

This is how I would do it. I'm including a ggplot2 version of plot as well because I find it better fitted for the way I think about plots. This version will account for the number of levels in p1. If you want to compensate for the number of model parameters, you will just have to adjust the way you construct xy to include all the relevant variables. I should point out that if you omit the newdata argument, fitting will be done on the dataset provided to lm.

t <- seq(0, 10, 1)
df <- data.frame(t = t,
                 y = 1.5+0.5*(-1)^t + (1.5+0.5*(-1)^t) * t,
                 p1 = as.factor(rep(c("p1", "p2"), 10)[1:11]))

fit <- lm(y ~ t * p1, data = df)

xy <- data.frame(t = t, p1 = rep(levels(df$p1), each = length(t)))
xy$fitted <- predict(fit, newdata = xy)

library(RColorBrewer) # for colors, you can define your own
cols <- brewer.pal(n = length(levels(df$p1)), name = "Set1") # feel free to ignore the warning

plot(x = df$t, y = df$y)
for (i in 1:length(levels(xy$p1))) {
  tmp <- xy[xy$p1 == levels(xy$p1)[i], ]
  lines(x = tmp$t, y = tmp$fitted, col = cols[i])
}

library(ggplot2)
ggplot(xy, aes(x = t, y = fitted, color = p1)) +
  theme_bw() +
  geom_point(data = df, aes(x = t, y = y)) +
  geom_line()



标签: r plot lm