R,按另一列中的值缩放直方图计数

Posted

技术标签:

【中文标题】R,按另一列中的值缩放直方图计数【英文标题】:R, Scale histogram counts by a value from another column 【发布时间】:2021-12-28 22:49:39 【问题描述】:

背景:我在不同地点进行了蛤蜊调查并测量了它们的大小。由于低潮、蛤蜊床的范围等不同,调查没有包括相同的总面积。因此,一些地点可能有较高的蛤密度(#/m^2)但面积较小,因此总计数为低,而其他人可能具有相反的特征(或任何其他组合)。

我正在尝试创建一个多面直方图以显示每个不同 sitesize 频率,同时消除每个 site 调查的 area 数量的影响。从本质上讲,我希望频率能够反映每个站点的密度(每单位面积的出现次数),这样我就可以跨站点进行比较,并查看大小分布和相对频率的总体差异。

以下是一些示例数据:

site<-c(rep("D",5),rep("C",10),rep("B",10),rep("A",20))
size<-c(1,2,2,2,3,
        1,1,2,2,2,2,2,2,3,3,
        1,1,2,2,2,2,2,2,3,3,
        1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3)
area<-c(rep(10,5),rep(20,10),rep(10,10),rep(20,20))
density<-c(rep(5/10,5),rep(10/20,10),rep(10/10,10),rep(20/20,20))
description<-c(rep("Low Density 0.5, Low Area 10",5),rep("Low Density 0.5, High Area 20",10),rep("High Density 1.0, Low Area 10",10),rep("High Density 1.0, High Area 20",20))
d<-data.frame(site,size,area,description)

我知道我可以用 y 轴上的基本计数绘制直方图,它显示了面积和密度的影响:

ggplot(d, aes(x=size,fill=site))+
  geom_histogram(aes(y=stat(count),group=site))+
  facet_grid(site~.)

受调查区域影响的计数直方图:

或者我可以缩放 y 轴以显示相对频率,因此所有站点的总和 = 1,这也说明了调查区域和密度的影响:

ggplot(d, aes(x=size,fill=site))+
  geom_histogram(aes(y=stat(count)/sum(count),group=site))+
  facet_grid(site~.)

所有站点的相对频率(受调查区域的影响):

或者我可以缩放 y 轴以通过 site 显示相对频率,因此每个站点内的总数 = 1,这消除了密度和面积的影响(不是我想要的,因为这只能让我比较差异尺寸分布,但不是密度):

ggplot(d, aes(x=size,fill=site))+
  geom_histogram(aes(y=stat(density*width),group=site))+
  facet_grid(site~.)

每个站点的相对频率:

我真的很想移除area 的影响,以便图表显示密度差异。对于此示例,它应如下图所示 注意我不得不操纵数据集来人为地创建这个图表作为例子

理想图示例:

谁能帮我弄清楚如何在消除调查总面积的影响的同时显示不同地点的密度差异?

提前谢谢你!

【问题讨论】:

【参考方案1】:

这是你想要的吗?

library(tidyverse)
d %>%
    count(site, size, area, description) %>%
    mutate(density = parse_number(word(description, 3))) %>%
    group_by(site) %>%
    mutate(adj = n / sum(n) / 3 * density) %>%
    ggplot(aes(size, adj, fill = description)) +
    geom_col() +
    facet_wrap(~site, ncol = 1)

【讨论】:

是的,从本质上讲,这就是我要寻找的东西。谢谢!我是否正确理解了命令-parse_number 被用于从description 中提取密度值?在我的真实数据集中,我有一列带有density,所以我想我可以删除该部分并直接使用density。你能解释一下在计算adj时使用3 * density的原因吗?那是因为有三个尺寸等级吗?如果是这样,当在真实数据集中绘制更广泛的尺寸(例如 5-165 毫米)时,我需要将其调整为箱数,对吗?关于如何做到这一点的任何提示? 是的,所以parse_number(word("Low Density 0.5", 3)) 会从该文本中提取0.5 作为数字。是的,我猜3*density 取决于箱的数量,并且基于我试图对给出您建议的输出的答案进行逆向工程,我认为它使用了该调整。您可以在 group_by(site) 行之后添加 add_count(size, name = "sizes") 以获取用于该计算的变量。 事实证明,只需将adj=n/sum(n)/density 与我的真实数据集一起使用就可以了。无需乘以 3。感谢您的帮助!

以上是关于R,按另一列中的值缩放直方图计数的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server:选择一列的计数,同时检查另一列中的不同值

R中是不是有一种方法,如果一列的值满足另一列中的某个标准,则该列的值应该是上面的值

使用 Filter 或 If Else 根据 R 中另一列中的值过滤指标

SQL - 为给定列中的值获取另一列的值

R:基于一个列的值存在于另一列中,生成虚拟变量

希望在直方图上编辑 X 轴以显示 R 中的大值 [重复]