【发布时间】:2011-04-27 13:44:49
【问题描述】:
我想在ggplot2 包中使用stat_density() 和facet_wrap() 为不同的分组创建内核密度图,但我想确保我对每个图使用相同的带宽。我可以确定stat_density() 对每个地块使用相同的带宽吗?
例如,使用diamonds:
library(ggplot2)
ggplot(diamonds, aes(x = carat)) +
stat_density() +
facet_wrap(~ cut) +
scale_x_log()
在文档中它显示我可以使用adjust 来调整自动带宽,但这只是应用倍数并让我回到原来的问题。 stat_density() 也有... 选项,但我一直无法通过density() 选项bw,像这样:
ggplot(diamonds, aes(x = carat)) +
stat_density(bw = 1) +
facet_wrap(~ cut) +
scale_x_log()
那么,如果stat_density() 没有在所有方面使用相同的带宽,有没有办法可以强制这样做?我用transform() 和density() 尝试了ddply() 解决方案,但这失败了,因为density() 不一定返回与输入相同数量的x 和y 值。有任何想法吗?谢谢!
编辑
看起来ggplot2 为每个方面分配了最佳带宽(看起来@Ramnath 和 Dianardo、Fortin 和 Lemieux Econometrica 1996 同意这一点),而不是我寻求的恒定带宽。但是,如果我确实想要所有方面的带宽恒定,那么我在下面的尝试会失败。
my.density <- function(x) {
temp <- density(x$carat, bw = 0.5)
return(data.frame(carat = temp$x, density = temp$y))
}
temp <- ddply(diamonds, .(cut), my.density)
ggplot(temp, aes(x = carat, y = density)) +
geom_point() +
facet_wrap(~ cut) +
scale_x_log()
Warning messages:
1: In match.fun(get(".transform", .))(values) : NaNs produced
2: In match.fun(get(".transform", .))(values) : NaNs produced
3: In match.fun(get(".transform", .))(values) : NaNs produced
4: In match.fun(get(".transform", .))(values) : NaNs produced
5: In match.fun(get(".transform", .))(values) : NaNs produced
6: Removed 84 rows containing missing values (geom_point).
7: Removed 113 rows containing missing values (geom_point).
8: Removed 98 rows containing missing values (geom_point).
9: Removed 98 rows containing missing values (geom_point).
10: Removed 106 rows containing missing values (geom_point).
【问题讨论】:
-
查看
stat_density的文档,它似乎使用了density的默认版本。进一步挖掘,查看density的文档,您会发现它使用bw.nrd0方法来计算带宽。您应该查看此描述并弄清楚如何预先转换您的数据,以便您能够实现您的目标。 -
@Ramnath -- 谢谢!我沿着那条路走,但我自己无法更接近答案。但也许这会产生我的基本问题,“哪些
stat_density()参数是使用来自所有方面的信息设置的?哪些是在每个方面设置的?” -
@richardh -- 我认为统计转换是在对数据进行分面后应用的。因此,如果
bw.nrd0方法根据数据计算带宽,那么您将在各个方面拥有不同的带宽。为了获得更多控制,我的建议是使用ddply并根据需要计算密度估计值,然后将其作为aesthetic传递给ggplot。如果你愿意,我可以做一个例子。出于好奇,您为什么要在所有地块上使用相同的带宽? -
@Ramnath -- 关于带宽的要点!我检查了这项技术的“参考”(Dinardo、Fortin 和 Lemieux Econometrica 1996),看起来他们确实使用了可变带宽,为每个方面进行了最佳设置。我会确保我们真的想要恒定的带宽。但是对于我自己的教育,我很想看看你会怎么做——我的方法失败了(我会在上面粘贴)。
-
@richard -- 实际上警告是由于
my.density中carat的负值。稍微修改一下你的代码就可以了:ggplot(temp, aes(x = carat, y = density)) + geom_line(subset = .(carat > 0)) + facet_wrap(~ cut) + scale_x_log()。让我知道这是否是您要找的东西