ggplot2直方图binwidth

3
我希望在一个图中创建多个直方图(使用facet_wrap)。 以下是可能的示例代码:
df <- data.frame(p1 = rnorm(100,5,2), p2 = rnorm(100,80,20), group = rep(LETTERS[1:4],25))

library(ggplot2)
library(reshape)

plotData <- melt(df, id.vars = "group", measure.vars = c("p1","p2")  )

m <- ggplot(plotData, aes(x = value, color = group, fill = group, group = group))
m <- m + geom_bar(position=position_dodge())
m <- m + facet_wrap( ~ variable,scales = "free_x")
print(m)

现在,我想修改它每个参数(“p1”,“p2”)创建的图形,比如说10个条形图。
到目前为止,我找不到一种方法来实现这一点,因为binwidth / breaks计算应该依赖于数据的子集。
这真的可能吗?
我想分享我的解决方案(取自上面链接的回答问题),扩展了直方图与密度曲线叠加的可能性,使其缩放到直方图计数:
df <- data.frame(p1 = rnorm(1000,5,2), p2 = rnorm(1000,80,20), group = rep(LETTERS[1:4],25))

library(ggplot2)
library(reshape)
library(plyr)

plotData <- melt(df, id.vars = "group", measure.vars = c("p1","p2")  )

nBins <- 10

groupedData <- dlply(plotData, .(variable))
groupedBinWidth <- llply(groupedData, .fun = function(data, nBins) {
  r <- range(data$value, na.rm = TRUE, finite = TRUE)
  widthOfBins = (r[2] - r[1])/nBins
  if (is.na(widthOfBins) || is.infinite(widthOfBins) || (widthOfBins <= 0)) widthOfBins <- NULL
  widthOfBins
}, nBins = nBins)

densData <- dlply(plotData, .(variable, group), .fun = function(subData){
  param <- subData$variable[1]
  group <- subData$group[1]
  d <- density(subData$value)
  bw <- groupedBinWidth[[param]]
  data.frame(x = d$x, y = d$y * nrow(subData) * bw , group = group, variable = param)
})

hls <- mapply(function(x, b) geom_bar(aes(x = value), position = position_dodge(), data = x, binwidth = b), 
              groupedData, groupedBinWidth)

dLay <- mapply(function(data) geom_density(data = data, aes(x = x, y = y), stat = "identity", fill = NA, size = 1), 
               densData)

m <- ggplot(plotData, aes(x = value, color = group, fill = group, group = group))
m <- m + hls
m <- m + dLay
m <- m + facet_wrap( ~ variable,scales = "free")
print(m) 

enter image description here


所以您想要直方图,每个组/面板有10个条形箱,还是我误解了您的意思? - fileunderwater
@fileunderwater:没错,那就是我想要得到的。 - Antje Janosch
@shadow:我没有看到这个问题;谢谢你提供的链接,它可能包含答案;我会去看一下。 - Antje Janosch
如果您不介意的话,将自己的解决方案发布为答案并接受它可能是一个更好的主意。 - tonytonov
我想,我无法回答这个问题,因为它被标记为重复问题。但是我可以将其作为答案提供给其他可能很好的问题,因为我的解决方案还在顶部添加了漂亮的密度图。 - Antje Janosch
1个回答

0

试试这个 - 这是真的丑陋的代码,但如果我理解你正确的话它会起作用。您可能希望尝试一下 geom_density 或者去掉 fill 使其更易读。

nbin<- 5
m <- ggplot(plotData, aes(x = value, color = group, fill = group, group = group))
m <- m + geom_histogram(data = subset(plotData, variable == "p1"), binwidth=diff(range(subset(plotData, variable == "p1")$value))/nbin)
m <- m + geom_histogram(data = subset(plotData, variable == "p2"),  binwidth=diff(range(subset(plotData, variable == "p2")$value))/nbin)
m <- m + facet_wrap( ~ variable,scales = "free_x")
print(m)

enter image description here


这段代码对于示例代码可以正常工作,但我需要使其适用于未知数量的参数(p1,p2,... pn)。 - Antje Janosch
@July 我猜你应该尝试从一个函数中调用直方图/子集操作,也许可以使用mapply。 - fileunderwater

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