如何绘制变量交互矩阵

时间:2014-05-12 21:42:25

标签: r data-visualization

我的问题很简单。假设我有一个响应变量(y)的数据,以及三个解释变量(x1,x2,x3)......

# Example data
set.seed(123)
my.data <- data.frame(y = c(seq(1,5,length=20)+rnorm(20)),
                     x1 = c(seq(5,1,length=20)+rnorm(20)),
                     x2 = c(seq(1,10, length=20)+rnorm(20)),
                     x3 = rnorm(20))

我制作了一个模特。我感兴趣的唯一互动是(仅双重互动):

# Model creation
m1 <- lm(y ~ x1*x2*x3, data = my.data); summary(m1)
# x1:x2       -0.05754    0.06413  -0.897    0.387
# x1:x3       -0.47773    1.18781  -0.402    0.695
# x2:x3       -0.14915    0.48975  -0.305    0.766

我能够通过此代码以所需方式(热图)可视化个人提取,但问题始终是一个接一个。例如,“x1:x2”的插入

# required packages
library(rms)
library(lattice)

ddI <- datadist(my.data)
options(datadist="ddI")

lininterp <- ols(y ~ x1*x2, data=my.data)

bplot(Predict(lininterp, x1=seq(c(min(my.data$x1)-1), c(max(my.data$x1)+1), length = 20),
                         x2=seq(c(min(my.data$x2)-1), c(max(my.data$x2)+1), length = 20)),
                         col.regions = colorRampPalette(c("red","yellow","darkgreen"))(100))

我有超过3个解释变量,因此绘图非常烦人。 我想得到类似这样的情节(下图),但它高于我的R编程技能:

enter image description here

我没有找到任何可以处理它的R package,因此我感谢任何有用的建议。

3 个答案:

答案 0 :(得分:2)

这是一个ggplot解决方案。这假定my.data的第一列有响应,而所有其他列都是解释变量。

library(ggplot2)
library(plyr)      # for .(...)

vars <- colnames(my.data)[2:ncol(my.data)]    # explanatory variables
vars <- data.frame(t(expand.grid(vars,vars)))
gg <- do.call(rbind,lapply(vars,function(v){
  v   <- as.character(v)
  fit <- lm(formula(paste("y~",v[1],"*",v[2])),my.data)
  r1  <- range(my.data[v[1]])
  r2  <- range(my.data[v[2]])
  df  <- expand.grid(seq(r1[1],r1[2],length=20),seq(r2[1],r2[2],length=20))
  colnames(df) <- v
  df$pred      <- predict(fit,newdata=df)
  colnames(df) <- c("x","y","pred")
  return(cbind(H=v[1],V=v[2],df))
}))

gg     <- data.frame(gg)                     # ggplot needs a data frame
labels <- aggregate(cbind(x,y)~H+V,gg,mean)  # labels for the diagonals

ggplot(gg)+
  geom_tile(subset=.(as.numeric(H) < as.numeric(V)),aes(x,y,fill=pred),height=1,width=1)+
  geom_text(data=labels, subset=.(H==V),aes(x,y,label=H),size=8)+
  facet_grid(V~H,scales="free")+
  scale_x_continuous(expand=c(0,0))+scale_y_continuous(expand=c(0,0))+
  scale_fill_gradientn(colours=colorRampPalette(c("red","yellow","darkgreen"))(100))+
  theme_bw()+
  theme(panel.grid=element_blank())

几点说明:

  • 我们必须在height中设置widthgeom_tile(...),否则瓷砖不会显示。 这是ggplot中的一个错误。(请参阅here)。
  • 我们使用subset=.(as.numeric(H) < as.numeric(V))仅平铺下三角形元素。
  • 我们在data=labels中使用subset=.(H==V)geom_text(...)来标记对角元素。
  • 我们使用expand=c(0,0)中的scale_x(y)_continuous(...)来完整填充面板。

答案 1 :(得分:1)

这样的事情应该让你开始(灵感来自this question的答案。)

plot1 <- bplot(Predict(lininterp,
               x1=seq(c(min(my.data$x1)-1), c(max(my.data$x1)+1), length = 20),
               x2=seq(c(min(my.data$x2)-1), c(max(my.data$x2)+1), length = 20)),
               col.regions = colorRampPalette(c("red","yellow","darkgreen"))(100))
library(gridExtra)
nullplot <- nullGrob()
grid.arrange(plot1, nullplot, plot1, plot1, ncol = 2)

enter image description here

你可以摆脱传说并单独绘制它。如果你想要的东西大小不同(比如传说)你可能会有更多的运气wq::layOut,就像我对链接问题的回答一样。

答案 2 :(得分:0)

我用@ jlhoward的回答制作了一个函数:

interaction.plot <- function(my.data, response.col, ignore = NULL) {
  vars <- colnames(my.data)[!(colnames(my.data) %in% c(response.col, ignore))]    # explanatory variables
  vars <- data.frame(t(expand.grid(vars,vars)))
  gg <- do.call(rbind,lapply(vars,function(v){
    v   <- as.character(v)
    fit <- lm(formula(paste(response.col,"~",v[1],"*",v[2])),my.data)
    r1  <- range(my.data[v[1]])
    r2  <- range(my.data[v[2]])
    df  <- expand.grid(seq(r1[1],r1[2],length=20),seq(r2[1],r2[2],length=20))
    colnames(df) <- v
    df$pred      <- predict(fit,newdata=df)
    colnames(df) <- c("x","y","pred")
    return(cbind(H=v[1],V=v[2],df))
  }))

  gg     <- data.frame(gg)                     # ggplot needs a data frame
  labels <- aggregate(cbind(x,y)~H+V,gg,mean)  # labels for the diagonals

  ggplot(gg)+
    geom_tile(subset=.(as.numeric(H) < as.numeric(V)),aes(x,y,fill=pred),height=1,width=1)+
    geom_text(data=labels, subset=.(H==V),aes(x,y,label=H),size=8)+
    facet_grid(V~H,scales="free")+
    scale_x_continuous(expand=c(0,0))+scale_y_continuous(expand=c(0,0))+
    scale_fill_gradientn(colours=colorRampPalette(c("red","yellow","darkgreen"))(100))+
    theme_bw()+
    theme(panel.grid=element_blank())
}

interaction.plot(data.set, response.col = 'y', ignore = c('age', 'height'))