我有一个适合的逻辑模型,比如我已保存的myfit
。我使用的数据帧的格式为(其中第一列是结果)。
medical10 age female nonwhite bmi smoked condxs insuredd smi2d
1 0 60 0 1 29.97 0 0 1 0
2 0 42 0 1 25.85 1 3 1 1
3 0 62 1 0 25.06 0 1 1 0
4 0 62 0 0 36.27 0 2 0 0
5 0 32 0 0 33.36 0 0 1 0
6 0 41 0 0 21.70 1 0 0 0
...
我想做的是为每个变量组合制作一个逻辑图(以这种形式:http://ww2.coastal.edu/kingw/statistics/R-tutorials/logistic.html)。
由于有8个变量,因此在x轴上有一个变量,而另一个变量保持不变,有2 ^ 8个变换。有没有办法可以使用ggplot2自动化绘图?
例如,如果' x'是年龄,我会得到bmi的平均值,然后选择0为女性,0为非白人,0为烟熏,0为condxs,0为保险人,0为smi2d。然后我会做一个预测并制作一个x对y的ggplot。
然而,这是相当乏味的,我希望有更好的方法?
答案 0 :(得分:3)
我不知道ggplot中有什么特别的东西可以让这很容易。但我确实找到了一种方法(虽然它比我预期的更多。也许其他人可以改进。无论如何,首先让我们定义一组更有用的样本数据
N<-100
set.seed(15)
invlogit <- function(x) exp(x)/(exp(x)+1)
dd <- transform(data.frame(
age=runif(N,30,60),
female=sample(0:1, N, replace=T),
white=sample(c("Y","N"), N, replace=T),
bmi=rnorm(N,30,2)),
medical=as.numeric(invlogit((-60+2*age-1.5*bmi+3*female)/10)>runif(N)))
fit<-glm(medical~. ,dd, family=binomial)
所以现在我们有了一些数据和模型。现在,我将定义一个辅助函数,该函数将预测单个变量的值,同时将其他变量保持为平均值。
predictone<-function(fit, var, xlim=NULL, fix=list(), n=101,
xname=var, type="response") {
tt <- terms(fit)
vv <- as.list(attr(tt, "variables"))[-c(1,attr(tt, "response")+1)]
vn <- sapply(vv, deparse)
stopifnot(var %in% vn)
others <- vn[vn != var]
def<-lapply(others, function(x) {
if(x %in% names(fix)) {
if(is.factor(val)) {
stopifnot(fix[[x]] %in% levels(val))
val[val==fix[[x]]][1]
} else {
fix[[x]]
}
} else {
val <- fit$data[[x]]
if(is.factor(val)) {
val[val==names(sort(table(val))[1])][1]
} else {
mean(val)
}
}
})
if(is.factor(fit$data[[var]])) {
newdata <- data.frame(def, unique(fit$data[[var]]))
} else {
if(is.null(xlim)) {
xlim <- range(fit$data[[var]])
}
newdata <- data.frame(def, seq(min(xlim), max(xlim), length.out=n))
}
names(newdata)<-c(others, var)
pp<-data.frame(newdata[[var]], predict(fit,newdata, type=type))
names(pp)<-c(xname, type)
attr(pp,"fixed")<-setNames(def, others)
pp
}
基本上,此函数用于计算所有其他变量的平均值,然后进行实际预测。我们可以将它与测试数据一起用来制作一堆带有
的图plots<-lapply(names(dd)[1:4], function(x) {
if(is.factor(dd[[x]])) {
ggplot(predictone(fit, x), aes_string(x=x, y="response")) + geom_point()
} else {
ggplot(predictone(fit, x), aes_string(x=x, y="response")) + geom_line()
}
})
require(gridExtra)
do.call(grid.arrange, plots)
将返回
请注意,因素的处理方式与常规数值不同。当您使用0/1对分类变量进行编码时,R不能说它们是分类的,因此它不能很好地推断出有意义的值。我建议您将0/1值转换为适当的因子变量。
答案 1 :(得分:3)
要在CRAN上发布的关于2015-01-01的R rms
包的更新包括一个新功能ggplot.Predict
(由ggplot()
调用),它提供了一种通用方法使用ggplot2
生成此类曲线,处理多个移动变量,交互等。您可以在https://github.com/harrelfe/rms/blob/master/man/ggplot.Predict.Rd查看一些示例用法。您可以使用rms
图形和lattice
函数使用当前版本的plot.Predict
完成所有这些操作。