如何在每列(按X轴)内缩放(归一化)ggplot2 stat_bin2d的值

7

我有一个ggplot的stat_bin2d "热力图"。

library(ggplot2)
value<-rep(1:5, 1000)
df<-as.data.frame(value)    
df$group<-rep(1:7, len=5000)
df<-df[sample(nrow(df), 3000), ]
ggplot(df, aes(factor(group), factor(value))) +stat_bin2d()

我尝试为aes添加填充:

aes(factor(group), factor(value),fill = (..count..)/mean(..count..))

作为模仿密度的一种方式,除以总数似乎并不被接受,但这并不是我想要的——它似乎是通过整个数据帧计数之和来计算的。我想要每个组(通过x轴)中值的计数按组内均值(或总和、或其他统计量)归一化的结果。不幸的是,sum(..count..) 似乎给出的是整个数据帧的计数总和,而不仅仅是某一列的总和。

如果这份数据对您有用,您介意点个赞吗?我仍然对解决方案感兴趣。 - MartinT
你有没有考虑计算你想要“填充”的数字,并将它们放入df中进行绘图? - aosmith
我相信 stat_bin2d() 函数会再次对新值进行分组... - MartinT
1
嗯,你可以试试看。但是,如果你手动计算每个组合的 fill 变量,那么 geom_tile 不就能胜任这份工作了吗? - aosmith
感谢您提供geom_tile建议 - 我会检查一下,这可能是一个选项(虽然费力且不太灵活)。可惜bin2d没有针对此的选项 - 似乎是这样。 - MartinT
1个回答

1

我知道这篇文章非常古老,但是当我尝试做同样的事情并且不想使用geom_tile时,我找到了它。我能够通过after_stat和一个规范化函数来实现它:

norm_across_y <- function(v, x, y){
    data.frame(v=v, x=x, y=y) %>%
        group_by(x) %>%
        mutate(v=v/((max(y)-min(y))/n()*sum(v))) %>%
        ungroup() %>%
        pull(v)
}

ggplot(data, aes(x=xvar, y=yvar)) +
    stat_density_2d_filled(aes(fill=after_stat(norm_across_y(density, x, y))), geom="raster", contour=FALSE, n=500) +
    geom_point(color="red", shape="x") +
    scale_x_continuous(expand=c(0,0)) +
    scale_y_continuous(expand=c(0,0)) +
    scale_fill_viridis_c(limits=c(0,NA))

这个功能会对x轴的每个切片进行归一化,使得沿着y轴的积分为1,这正是我的使用情况。


可能需要明确指定“数据”。 - yeahman269

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