面对ggplot / R中的一组等高线图?

时间:2013-07-30 22:40:45

标签: r ggplot2 contour

编辑:我同意Roland的说法,我不需要在Shiny特定的内容上花费所有文字。删除并添加了数据框在考虑之后应该是什么样子的要点。


EDIT_2:虽然shiny内容与问题无关,I created an example使用Roland的解决方案,如果路人有兴趣看看我在做什么有了这个。对图形加载有耐心;它可能有点慢。


我正在尝试在R和shiny中绘制一组预测的建模数据。我有四个变量,我想在等高线图中显示它们的相互作用。对于每个变量,我让用户定义一个范围以及一个保持值。每个变量有两种情况:

  • 用作轴变量之一:范围决定了我在模型中为该变量预测新响应的值
  • 没有直接在图中显示:保持值用于将非特征变量设置为常量值,以便我对其他两个变量的预测仅产生一个唯一/单个表面{{ 1}}每个zx组合的值

我遇到了处理数据的问题,这种方式对于生成等高线图网格非常友好。我理想地喜欢一个屏幕,显示其他四个变量之间的6个相互作用( 4 C 2 )。

我基本上需要两组数据:

  • 用于训练模型的输入数据集的原始形式之一(以便我可以y获取用于predict(model, newData)值的输出列
  • 上一个用于绘图/构图
  • 的子集/重新排列形式

对于方面友好的版本,这是我需要的(在我看来;也许有更好的方法):

z

通过这种方式,我有| x | y | z | col | row | |----------+----------+---+-----+-----| | var1_min | var2_min | z | 1 | 1 | | var1_min | ... | z | 1 | 1 | | var1_min | var2_max | z | 1 | 1 | | ... | ... | z | 1 | 1 | | var1_max | var2_min | z | 1 | 1 | | var1_max | ... | z | 1 | 1 | | var1_max | var2_max | z | 1 | 1 | |----------+----------+---+-----+-----| | var1_min | var3_min | z | 1 | 2 | | var1_min | ... | z | 1 | 2 | | var1_min | var3_max | z | 1 | 2 | | ... | ... | z | 1 | 2 | | var1_max | var3_min | z | 1 | 2 | | var1_max | ... | z | 1 | 2 | | var1_max | var3_max | z | 1 | 2 | |----------+----------+---+-----+-----| | ... | ... | z | | | |----------+----------+---+-----+-----| | var3_min | var4_min | z | 3 | 2 | | var3_min | ... | z | 3 | 2 | | var3_min | var4_max | z | 3 | 2 | | ... | ... | z | 3 | 2 | | var3_max | var4_min | z | 3 | 2 | | var3_max | ... | z | 3 | 2 | | var3_max | var4_max | z | 3 | 2 | |----------+----------+---+-----+-----| x值,来自模型的相应预测响应的列,以及创建y(使用2x3或3x2)方面。

对于预测数据框,表单必须与我的初始预测数据匹配,并且几乎就像上面的演员/广泛版本:

facet_grid

我将其输入模型以获得在等高线图中用作| var1 | var2 | var3 | var4 | |-----------+-----------+-----------+-----------| | var1_min | var2_min | var3_hold | var4_hold | | var1_min | ... | var3_hold | var4_hold | | var1_min | var2_max | var3_hold | var4_hold | | ... | ... | var3_hold | var4_hold | | var1_max | var2_min | var3_hold | var4_hold | | var1_max | ... | var3_hold | var4_hold | | var1_max | var2_max | var3_hold | var4_hold | | ... | ... | ... | ... | | var1_hold | var2_hold | var3_max | var4_min | | var1_hold | var2_hold | var3_max | ... | | var1_hold | var2_hold | var3_max | var4_max | 的预测响应。

它也变得棘手,因为我并不总是希望变量按照它们的自然z顺序排列,因为我需要将它们排列成在小平面行或小平面列之间具有一个公共轴标度(可以是,不需要两者兼有)。我会安排这样的组合:

ith

现在我可以有三列和两行方面,第1列包含共享| x | y | row | column | |------+------+-----+--------| | var1 | var2 | 1 | 1 | | var1 | var3 | 2 | 1 | | var2 | var3 | 1 | 2 | | var2 | var4 | 2 | 2 | | var4 | var3 | 1 | 3 | | var4 | var1 | 2 | 3 | 轴,第2列包含var1,第3列包含var2

我想知道手动使用var4六个独特的变量组合。完成之后,我意识到每一行都会将两个变量设置为其保持值,所以也许我可以创建这六个组合的列表,然后将非保持值变量提取到绘图数据框的两个新列中?

有什么建议吗?


以下是我尝试使用三个变量的一个hackish示例,我们只关注expand.gridvar1之间的互动:

c(var2, var3)

不幸的是,这给我留下了很多案例,其中# the min/max arguments to `seq()` are like the user-defined range # take the second argument to `c()` is to be user-defined hold value library(ggplot2) var1 <- seq(0, 25, length.out = 10) # hold value = 11.1 var2 <- seq(5, 45, length.out = 10) # hold value = 17 var3 <- seq(55, 90, length.out = 10) # hold value = 72 # create combinations between var1 and var2, with var3 held test_data <- expand.grid(var1 = var1, var2 = var2, var3 = 72) # same, but for var1 vs. var3, with var2 held test_data <- rbind(test_data, expand.grid(var1 = var1, var2 = 17, var3 = var3)) # create response; analog to using predict() in real life test_data$resp <- (test_data$var1 + test_data$var2) / test_data$var3 # facet variable placeholder and filling in test_data$facet <- rep("", nrow(test_data)) test_data[test_data$var2 == 17, "facet"] <- "var1 vs. var3" test_data[test_data$var3 == 72, "facet"] <- "var1 vs. var2" # now I melted test_data2 <- melt(test_data, id.vars = c("var1", "resp", "facet")) 填入了valuevar2的所有保留值,所以我不得不将其删除:

var3

现在,我能够做到这一点:

test_data2 <- test_data2[test_data2$value != 72 & test_data2$value != 17, ]

得到了我正在寻找的球场。现在我想我需要一种优雅的方式来进行组合并保持值而不会产生难看的结果。

enter image description here

这是一个更新版本,现在我得到如何在行/列的相同轴上绘图(因为我有两列和一行,我需要y轴对于两个面都是相同的,在本例中是{ {1}}):

ggplot(test_data2, aes(x = var1, y = value, z = resp)) +
    stat_contour() + facet_grid(~ facet)

enter image description here

1 个答案:

答案 0 :(得分:2)

我真的希望我能正确理解你。

我创建了自己的示例,它实际上适合模型。

#some data
set.seed(42)
x1 <- rnorm(20)
x2 <- runif(20)
x3 <- rpois(20,10)
x4 <- rexp(20)
y <- 10 + 2*x1 + 3*x2^2 + 4*x3 +5*x4 + rnorm(20, sd=0.1)

dat <- data.frame(x1, x2, x3, x4, y)

#fit the model
fit <- lm(y~x1+I(x2^2)+x3+x4, data=dat)
summary(fit)

#ranges and fixed values
fix_x <- c(0.3, 0.4, 15, 1)
min_x <- c(-3, 0, 5, 0)
max_x <- c(3, 1, 20, 7)

#all combinations
combis <- combn(seq_len(ncol(dat)-1),2)
#number of x-values 
#(warning! don't make too large since expand.grid is used)
n <- 100

#create new data and predict for each combination
newdat <- lapply(seq_len(ncol(combis)),
                 function(i) {
                   gr <- expand.grid(seq(from=min_x[combis[1,i]],
                                         to=max_x[combis[1,i]],
                                         length.out=n),
                                     seq(from=min_x[combis[2,i]],
                                         to=max_x[combis[2,i]],
                                         length.out=n))

                   newdat <- as.data.frame(matrix(nrow=nrow(gr), ncol=ncol(dat)-1))
                   newdat[,combis[,i]] <- gr
                   newdat[,-combis[,i]] <- matrix(rep(fix_x[-combis[,i]],each=nrow(gr)), nrow=nrow(gr))

                   newdat <- as.data.frame(newdat)
                   names(newdat) <- head(names(dat),-1)

                   newdat$y <- predict(fit, newdata=newdat)

                   newdat$comb <- paste(combis[,i],collapse=" vs. ")
                   #rename so rbind works as needed
                   names(newdat)[combis[,i]] <- c("xa","xb")
                   names(newdat)[-combis[,i]] <- c(paste0("fix",letters[seq_len(ncol(dat)-3)]), "y", "comb")
                   newdat
                 })

newdat <- do.call(rbind,newdat)

#plot
library(ggplot2)
ggplot(newdat, aes(x=xa, y=xb, z=y)) + 
  stat_contour() + 
  facet_wrap(~comb, scales="free", ncol=2) +
  xlab("") +
  ylab("")

enter image description here