下面有一个虚拟数据框,我想计算站点分布之间的成对重叠百分比.基本上,site1和site2重叠的百分比是多少,site2与site3,site1与site3?

structure(list(site = c("site1", "site1", "site1", "site1", "site1", 
"site1", "site1", "site1", "site1", "site1", "site2", "site2", 
"site2", "site2", "site2", "site2", "site2", "site2", "site2", 
"site2", "site3", "site3", "site3", "site3", "site3", "site3", 
"site3", "site3", "site3", "site3"), total = c(0.4191, 0.2844, 
0.2611, 0.2743, 0.2938, 0.3287, 0.2992, 0.4062, 0.2946, 0.2671, 
0.3832, 0.3875, 0.3118, 0.4506, 0.4215, 0.4266, 0.3518, 0.4446, 
0.4255, 0.3208, 0.2377, 0.2818, 0.2526, 0.2425, 0.2973, 0.4539, 
0.357, 0.2865, 0.3624, 0.3026)), class = c("grouped_df", "tbl_df", 
"tbl", "data.frame"), row.names = c(NA, -30L), groups = structure(list(
    site = c("site1", "site2", "site3"), .rows = structure(list(
        1:10, 11:20, 21:30), ptype = integer(0), class = c("vctrs_list_of", 
    "vctrs_vctr", "list"))), row.names = c(NA, -3L), class = c("tbl_df", 
"tbl", "data.frame"), .drop = TRUE))

ggplot(aes(x = total, group = site, fill = site)) +
  geom_density(adjust = 1.5, alpha = 0.3) 

enter image description here

推荐答案

你的密度图可能有点误导,因为密度图会超出x轴上数据的实际范围,并且倾向于给出比数据中实际存在的重叠高得多的估计值.更好的可视化方法可能是:

df %>%
  group_by(site) %>%
  mutate(site = factor(site)) %>%
  summarize(xmin = min(total), xmax = max(total), 
            ymin = as.numeric(site), ymax = as.numeric(site)) %>%
  ggplot() +
  geom_segment(aes(x = xmin, xend = xmax, y = ymin, yend = ymax, color = site),
               size = 2) +
  scale_y_continuous(breaks = 1:3, expand = c(1, 1)) +
  theme_bw()
#> `summarise()` has grouped output by 'site'. You can override using the
#> `.groups` argument.

创建成对比较的一种方法是使用expand.grid获得所有唯一的站点对:

comp_df <- expand.grid(A = sort(unique(df$site)), 
                       B = sort(unique(df$site)))

然后我们需要一个函数,它将取两个站点的名称,并计算它们的范围之间的重叠百分比.我在这里用一种非常简单的方法,使用简单的算术:

comp_func <- function(a, b) {
  max_a <- max(df$total[df$site == a])
  min_a <- min(df$total[df$site == a])
  max_b <- max(df$total[df$site == b])
  min_b <- min(df$total[df$site == b])
  max_b <- ifelse(max_b > max_a, max_a, max_b)
  min_b <- ifelse(min_b < min_a, min_a, min_b)
  (max_b - min_b) / (max_a - min_a)
}

现在我们可以将这个函数应用到比较数据框的行中,这样我们就可以得到每一对独特的站点的成对估计.

comp_df$overlap <- unlist(Map(comp_func, a = comp_df$A, b = comp_df$B))

最后,我们希望删除测试区域与自身重叠的条目,因为这将始终是100%:

comp_df <- comp_df[comp_df$A != comp_df$B,]

最终结果可以根据我们的图进行合理性判断,并且可以看出是有道理的(overlap列是A列中的场地与B列中的场地重叠的比例)

comp_df
#>       A     B   overlap
#> 2 site2 site1 0.7730548
#> 3 site3 site1 0.7308048
#> 4 site1 site2 0.6791139
#> 6 site3 site2 0.6419981
#> 7 site1 site3 1.0000000
#> 8 site2 site3 1.0000000

例如,我们可以看到,场地1和场地2与场地3的重叠率为100%,正如我们在图中所确认的,而场地1与场地2的重叠率约为68%.

reprex package(v2.0.1)于2022年4月25日创建

R相关问答推荐

计算具有奇数日期的运行金额

如何在geom_col中反转条

R函数,用于生成伪随机二进制序列,其中同一数字在一行中不出现超过两次

2个Rscript.exe可执行文件有什么区别?

如何将Which()函数用于管道%>;%

查找所有站点的最小值

解析嵌套程度极高的地理数据

R基于变量组合创建新的指标列

roxygen2正在处理太多的文件

将美学添加到ggploy中的文本标签

使用其他DF中的文件名将列表中的每个元素保存到文件中

从字符串01JAN2021创建日期

在R中,有没有什么方法可以根据一列中的多个值来过滤行?

获取列位置

列中的所有值都是真的吗?忽略NA

ggplot2标记位置未居中

我正在try 在R Studio中制作一张世界 map ,该 map 使用相对于数字变量的国家 colored颜色 填充

按特定顺序列出数据

如何根据区间的重叠程度对区间进行分类?

提取字符串的一部分并将其粘贴到其他组