绘制Logistic方程拟合或ggplot2中的许多变量

时间:2014-12-20 00:09:23

标签: r plot ggplot2

我有一个适合的逻辑模型,比如我已保存的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。

然而,这是相当乏味的,我希望有更好的方法?

2 个答案:

答案 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)

将返回

enter image description here

请注意,因素的处理方式与常规数值不同。当您使用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完成所有这些操作。