编辑:我同意Roland的说法,我不需要在Shiny特定的内容上花费所有文字。删除并添加了数据框在考虑之后应该是什么样子的要点。
EDIT_2:虽然shiny
内容与问题无关,I created an example使用Roland的解决方案,如果路人有兴趣看看我在做什么有了这个。对图形加载有耐心;它可能有点慢。
我正在尝试在R和shiny
中绘制一组预测的建模数据。我有四个变量,我想在等高线图中显示它们的相互作用。对于每个变量,我让用户定义一个范围以及一个保持值。每个变量有两种情况:
z
和x
组合的值我遇到了处理数据的问题,这种方式对于生成等高线图网格非常友好。我理想地喜欢一个屏幕,显示其他四个变量之间的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.grid
和var1
之间的互动:
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"))
填入了value
和var2
的所有保留值,所以我不得不将其删除:
var3
现在,我能够做到这一点:
test_data2 <- test_data2[test_data2$value != 72 & test_data2$value != 17, ]
得到了我正在寻找的球场。现在我想我需要一种优雅的方式来进行组合并保持值而不会产生难看的结果。
这是一个更新版本,现在我得到如何在行/列的相同轴上绘图(因为我有两列和一行,我需要y轴对于两个面都是相同的,在本例中是{ {1}}):
ggplot(test_data2, aes(x = var1, y = value, z = resp)) +
stat_contour() + facet_grid(~ facet)
答案 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("")