多组密度图

4

我正在尝试使用mice软件包进行多重插补之后,使用ggplot2生成类似于lattice packagedensityplot()函数。以下是可重现的示例:

require(mice)
dt <- nhanes
impute <- mice(dt, seed = 23109)
x11()
densityplot(impute)

这将产生:

我想在ggplot中改进的密度图输出

我希望能更好地控制输出(同时也将此作为ggplot的学习练习)。因此,对于bmi变量,我尝试了以下操作:

bar <- NULL
for (i in 1:impute$m) {
    foo <- complete(impute,i)
    foo$imp <- rep(i,nrow(foo))
    foo$col <- rep("#000000",nrow(foo))
    bar <- rbind(bar,foo)
}

imp <-rep(0,nrow(impute$data))
col <- rep("#D55E00", nrow(impute$data))
bar <- rbind(bar,cbind(impute$data,imp,col))
bar$imp <- as.factor(bar$imp)

x11()
ggplot(bar, aes(x=bmi, group=imp, colour=col)) + geom_density()
+ scale_fill_manual(labels=c("Observed", "Imputed"))

这会生成以下内容: enter image description here 因此,它存在几个问题:
1.颜色不正确。似乎我试图控制颜色的尝试完全是错误的/被忽略了。 2.有不必要的水平和垂直线条。 3.我想让图例显示Imputed和Observed,但我的代码会出现错误“一元运算符的参数无效”。 此外,似乎用`densityplot(impute)`一行就可以完成的工作需要做很多工作 - 所以我想知道是否完全走了弯路? 4.图的范围似乎不正确。

请参阅有关在R中比较组间密度的主题的以下帖子:http://eeyore.ucdavis.edu/stat141/MultipleDensityPlots.html - Jeromy Anglim
2个回答

6
使用 ggplot2 更加复杂的原因是你使用了 mice 包中的 densityplot 函数(确切来说是 mice::densityplot.mids - 可以查看其代码),而不是使用 lattice 本身的函数。该函数已经内置了绘制 mice 中的 mids 结果类所需的所有功能。如果你尝试使用 lattice::densityplot,你会发现它和使用 ggplot2 一样需要很多工作。
但是,下面是如何使用 ggplot2 实现:
require(reshape2)
# Obtain the imputed data, together with the original data
imp <- complete(impute,"long", include=TRUE)
# Melt into long format
imp <- melt(imp, c(".imp",".id","age"))
# Add a variable for the plot legend
imp$Imputed<-ifelse(imp$".imp"==0,"Observed","Imputed")

# Plot. Be sure to use stat_density instead of geom_density in order
#  to prevent what you call "unwanted horizontal and vertical lines"
ggplot(imp, aes(x=value, group=.imp, colour=Imputed)) + 
    stat_density(geom = "path",position = "identity") +
    facet_wrap(~variable, ncol=2, scales="free")

输入图像描述

但是你可以看到这些图的范围比densityplot还要小。这种行为应该由stat_density的参数trim控制,但是它似乎不能工作。在修复了stat_density的代码之后,我得到了以下的图表:

输入图像描述

虽然不完全与densityplot原始图相同,但更接近了。

编辑:对于真正的解决方案,我们需要等待ggplot2的下一个主要版本,请参见github


太好了。谢谢 (+1)。我可以问一下你是如何修复代码以扩展范围的吗? - Joe King
当然。请看这里。只是一个快速的hack。我还在摸索包开发,等我有时间并找到更好的解决方案后,我会将其提交给ggplot2的开发人员。 - ROLO
再次感谢。这很好用。很抱歉又要问一个问题,但我是R的初学者 - 我理解您对代码所做的更改,但您能告诉我如何找到您必须更改的代码吗? - Joe King
我在 github 上查找了它。 - ROLO

5
你可以请求 Hadley 为这个 mids 类添加一个 fortify 方法。例如:
fortify.mids <- function(x){
 imps <- do.call(rbind, lapply(seq_len(x$m), function(i){
   data.frame(complete(x, i), Imputation = i, Imputed = "Imputed")
 }))
 orig <- cbind(x$data, Imputation = NA, Imputed = "Observed")
 rbind(imps, orig)
}

ggplot在绘图之前会将非数据框对象“加固”

ggplot(fortify.mids(impute), aes(x = bmi, colour = Imputed, 
   group = Imputation)) +
geom_density() + 
scale_colour_manual(values = c(Imputed = "#000000", Observed = "#D55E00"))

请注意每个命令都以“+”结尾。否则,该命令将被视为不完整。这就是图例未更改的原因。以“+”开头的行导致错误。enter image description here您可以溶解fortify.mids的结果,将所有变量绘制在一个图表中。
library(reshape)
Molten <- melt(fortify.mids(impute), id.vars = c("Imputation", "Imputed"))
ggplot(Molten, aes(x = value, colour = Imputed, group = Imputation)) + 
geom_density() + 
scale_colour_manual(values = c(Imputed = "#000000", Observed = "#D55E00")) +
facet_wrap(~variable, scales = "free")

enter image description here


这非常好。谢谢,(+1)。我可以问一下,是否有可能防止水平和垂直线绘制? - Joe King
geom_density() 创建的是多边形,而不是线条。因此会出现垂直和水平的线条。多边形的好处在于可以使用轮廓颜色和填充颜色。请参见http://had.co.nz/ggplot2/stat_density.html。 - Thierry

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接