用R中的facet_wrap标准化ggplot2密度

时间:2013-07-07 22:42:34

标签: r plot ggplot2

我正在使用geom_density从数据框制作一系列密度图,并使用facet_wrap按条件显示,如:

ggplot(iris) + geom_density(aes(x=Sepal.Width, colour=Species, y=..count../sum(..count..))) + facet_wrap(~Species)

当我这样做时,y轴刻度似乎不代表面板中每个Species的百分比,而是所有物种中所有总数据点的百分比。

我的问题是:如何制作,..count..中的geom_density变量指的是每个面板的每个Species集合中的项目数,以便{ {1}}的y轴对应于“virginica数据点的分数”?

另外,有没有办法让ggplot2输出它用于virginica..count..的值,以便我可以验证它使用的是什么数字?

修改:我误解了sum(..count..)即使对于单个geom_densitySpecies也不是百分比:

..count../sum(..count..)

所以我修改过的问题:我怎样才能将密度图作为每个bin中数据的一小部分?我是否必须使用ggplot(iris[iris$Species == 'virginica',]) + geom_density(aes(x=Sepal.Width, colour=Species, y=..count../sum(..count..))) + facet_wrap(~Species) stat_density?我只想让y轴成为数据点的百分比/分数

3 个答案:

答案 0 :(得分:5)

不幸的是,你要求ggplot2做的是为每个方面定义单独的y,它在语法上不能做AFAIK。

所以,为了回应你在评论主题中提到“你只是想要一个基本的直方图”,我建议改为使用geom_histogram,或者,如果你偏向于行而不是条形,{{1 }}:

geom_freqpoly

enter image description here

**注意:在我上面的例子中,geom_freqpoly也可以代替geom_histogram。为了提高效率,我在一个图中添加了两个。

希望这有帮助。

编辑:好吧,我设法找到了一个快速而肮脏的方式来获得你想要的东西。它要求您安装并加载ggplot(iris, aes(Sepal.Width, ..count..)) + geom_histogram(aes(colour=Species, fill=Species), binwidth=.2) + geom_freqpoly(colour="black", binwidth=.2) + facet_wrap(~Species) 。提前道歉;就RAM使用而言,这可能不是最有效的方法,但它确实有效。

首先,让我们在开放中获取虹膜(我使用RStudio所以我习惯在窗口中看到所有对象):

plyr

现在,我们可以使用d <- iris 来计算属于x轴的每个独特测量的个体数量(这里我使用了Sepal.Length而不是Sepal.Width,给自己一点点更多范围,只是为了在绘制时看到组之间的更大差异。)

ddply

请注意new <- ddply(d, c("Species", "Sepal.Length"), summarize, count=length(Sepal.Length)) 会根据引用的变量自动对输出data.frame进行排序。

然后我们可以将data.frame分成每个独特的条件 - 在虹膜的情况下,三个物种中的每一个(我确信有更平滑的方式去做,如果你'重新处理大量数据不建议继续创建相同data.frame的子集,因为你可以最大化你的RAM ... ...

ddply

...并再次使用set <- new[which(new$Species%in%"setosa"),] ver <- new[which(new$Species%in%"versicolor"),] vgn <- new[which(new$Species%in%"virginica"),] 来计算每次测量下的个体比例,但每个物种的分别

ddply

然后我们将所需的所有内容放入一个数据集中,并从工作区中删除所有垃圾。

prop <- rbind(ddply(set, c("Species"), summarize, prop=set$count/sum(set$count)),
              ddply(ver, c("Species"), summarize, prop=ver$count/sum(ver$count)),
              ddply(vgn, c("Species"), summarize, prop=vgn$count/sum(vgn$count)))

我们可以在y上使用小平面特定的比例来制作我们的数字。请注意,我现在使用new$prop <- prop$prop rm(list=ls()[which(!ls()%in%c("new", "d"))]) ,因为geom_line已自动订购了您的data.frame。

ddply

facet_wrap with facet-specific proportions

ggplot(new, aes(Sepal.Length, prop)) + 
  geom_line(aes(colour=new$Species)) +
  facet_wrap(~Species)

答案 1 :(得分:0)

也许使用table()和barplot()你可能得到你需要的东西。我仍然不确定这是不是你想要的......

barplot(table(iris[iris$Species == 'virginica',1]))

使用ggplot2

tb <- table(iris[iris$Species == 'virginica',1])
tb <- as.data.frame(tb)
ggplot(tb, aes(x=Var1, y=Freq)) + geom_bar()

答案 2 :(得分:0)

将参数scales='free_y'传递给facet_wrap()应该可以解决问题。