Jak można wykreślić ciągły przez ciągłe interakcje w ggplot2?

11

Powiedzmy, że mam dane:

x1 <- rnorm(100,2,10)
x2 <- rnorm(100,2,10)
y <- x1+x2+x1*x2+rnorm(100,1,2)
dat <- data.frame(y=y,x1=x1,x2=x2)
res <- lm(y~x1*x2,data=dat)
summary(res)

Chcę wykreślić ciągłe przez ciągłą interakcję tak, że x1 jest na osi X, a x2 jest reprezentowany przez 3 linie, jedna reprezentująca x2 przy wyniku Z wynoszącym 0, jedna przy wyniku Z wynoszącym +1, a druga przy wyniku Z-score równy -1, z każdą linią osobnym kolorem i oznaczony. Jak mogę to zrobić za pomocą ggplot2?

Na przykład może to wyglądać mniej więcej tak (choć oczywiście z różnymi kolorowymi liniami zamiast z różnymi rodzajami linii): Przykładowy obraz

russellpierce
źródło
Czy możesz pokazać przykładowy obraz z innego pakietu / oprogramowania lub podać bardziej szczegółowy opis tego, co chcesz wydrukować?
daroczig

Odpowiedzi:

9

Oto moja wersja z symulowanym zestawem danych:

x1 <- rnorm(100,2,10)
x2 <- rnorm(100,2,10)
y <- x1+x2+x1*x2+rnorm(100,1,2)
dat <- data.frame(y=y,x1=x1,x2=x2)
res <- lm(y~x1*x2,data=dat)
z1 <- z2 <- seq(-1,1)
newdf <- expand.grid(x1=z1,x2=z2)

library(ggplot2)
p <- ggplot(data=transform(newdf, yp=predict(res, newdf)), 
            aes(y=yp, x=x1, color=factor(x2))) + stat_smooth(method=lm)
p + scale_colour_discrete(name="x2") + 
  labs(x="x1", y="mean of resp") + 
  scale_x_continuous(breaks=seq(-1,1)) + theme_bw()

Pozwalam ci zarządzać szczegółami na temat etykiet osi x / y i pozycjonowania legend.

wprowadź opis zdjęcia tutaj

chl
źródło
Wygląda dobrze, z wyjątkiem (oczywiście) najpierw musielibyśmy skalować (x1) i skalować (x2).
russellpierce
1
@drknexus Tak, oczywiście (w moich początkowych testach użyłem standaryzowanych wariantów N (0; 1) zamiast twojego).
chl
5

Obliczanie szacunków dla y z wynikiem Z wynoszącym 0 ( kolumna y0 ), -1 ( kolumna y1m ) i 1 ( kolumna y1p ):

dat$y0 <- res$coefficients[[1]] + res$coefficients[[2]]*dat$x1 + res$coefficients[[3]]*0 + res$coefficients[[4]]*dat$x1*0
	dat$y1m <- res$coefficients[[1]] + res$coefficients[[2]]*dat$x1 + res$coefficients[[3]]*-1 + res$coefficients[[4]]*dat$x1*-1
dat$y1p <- res$coefficients[[1]] + res$coefficients[[2]]*dat$x1 + res$coefficients[[3]]*1 + res$coefficients[[4]]*dat$x1*1

Rysowanie linii z bazą plot():

plot(dat$x1, dat$y0, type="l", xlab="x1", ylab="Estimates")
lines(dat$x1, dat$y1m, col="red")
lines(dat$x1, dat$y1p, col="blue")

wprowadź opis zdjęcia tutaj

Aby użyć ggplot, możesz wywołać geom_line :

ggplot(dat, aes(x1, y0)) + geom_line() +
    geom_line(aes(x1, y1m), color="red") +
    geom_line(aes(x1, y1p), color="blue") +
    theme_bw() + opts(title="") + xlab("x1") + ylab("Estimates")

wprowadź opis zdjęcia tutaj

daroczig
źródło
2
możesz uzyskać prognozy za pomocą przewidywania. dat [, "y0"] <- przewidywanie (res, newdata = data.frame (x1 = dat [, "x1"], x2 = 0)) Zapisuje trochę pisania.
mpiktas
@mpiktas: dziękuję, nie wiedziałem o predict, ale wydaje się przydatny.
daroczig
1
Zawsze zalecałbym użycie przewidywania zamiast samodzielnego obliczania nachyleń - jest to o wiele prostsze, zwłaszcza gdy masz interakcje lub komponenty nieliniowe.
hadley 27.01.11