You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何生成组间成对共享观测计数矩阵并实现可视化?

解决方案:生成组间共享观测计数矩阵并可视化

针对你的需求,我会分步骤用dplyr/tidyr和Base R两种方式实现,最后用热力图展示结果:

第一步:准备示例数据

先把你提供的数据转换成可测试的格式:

library(dplyr)
library(tidyr)
library(ggplot2)

# 你的原始数据
df <- tibble(
  Animal = c("Cat", "Cat", "Cat", "Bat", "Bat", "Bat", "Bat", "Mouse", "Mouse", "Mouse", "Deer", "Deer", "Deer"),
  Sector = c(1,1,2,2,3,3,3,1,2,2,2,2,2),
  Time = c("Night", "Night", "Night", "Night", "Night", "Night", "Night", "Day", "Night", "Night", "Day", "Night", "Night"),
  Group = c("A", "B", "B", "A", "C", "A", "B", "B", "A", "B", "A", "B", "C")
)

方法1:用dplyr实现

步骤1:标记每个观测所属的组

先把Animal+Sector+Time作为唯一观测标识,收集每个观测对应的所有组:

obs_groups <- df %>%
  distinct(Animal, Sector, Time, Group) %>% # 确保组内观测不重复(题目已说明,这里做双重保障)
  group_by(Animal, Sector, Time) %>%
  summarise(groups = list(Group), .groups = "drop")

步骤2:生成所有组对并计算共享数

先提取所有唯一组,再生成所有可能的组对,最后统计每对组的共享观测数量:

# 获取所有唯一组
all_groups <- unique(df$Group)

# 生成所有组的笛卡尔积(包括组自身配对)
group_pairs <- expand.grid(Group1 = all_groups, Group2 = all_groups, stringsAsFactors = FALSE)

# 计算每对组的共享观测数
shared_counts <- group_pairs %>%
  rowwise() %>%
  mutate(
    count = sum(obs_groups$groups %>% purrr::map_lgl(~ all(c(Group1, Group2) %in% .x)))
  ) %>%
  ungroup()

步骤3:转换为矩阵格式

如果需要得到矩阵形式的结果:

shared_matrix <- shared_counts %>%
  pivot_wider(names_from = Group2, values_from = count) %>%
  column_to_rownames("Group1") %>%
  as.matrix()

# 输出结果
shared_matrix
#>    A B C
#> A  4 3 1
#> B  3 5 2
#> C  1 2 2

注:矩阵中A-A的值是组A的总观测数,A-B是两组共享的3个观测,和你的示例完全一致。


方法2:用Base R实现(更高效)

利用矩阵乘法的特性,一步得到组间共享计数矩阵,适合大数据量:

# 1. 生成观测的唯一标识
df$obs_id <- with(df, paste(Animal, Sector, Time, sep = "_"))

# 2. 创建交叉表:行=观测,列=组,值为1表示该观测属于对应组
cross_tab <- table(df$obs_id, df$Group)
cross_tab <- (cross_tab > 0) * 1 # 转换为二进制(消除组内重复的影响)

# 3. 矩阵乘法计算共享数:转置交叉表 × 交叉表,得到组间共享计数矩阵
shared_matrix_base <- t(cross_tab) %*% cross_tab

# 输出结果
shared_matrix_base
#>    A B C
#> A  4 3 1
#> B  3 5 2
#> C  1 2 2

这个方法的核心逻辑是:两组的共享观测数 = 两组观测向量的点积,矩阵乘法会自动完成所有组对的计算,效率很高。


可视化:带0值的热力图

用ggplot2绘制热力图,清晰展示所有组对的共享计数(包括0值):

shared_counts %>%
  ggplot(aes(x = Group1, y = Group2, fill = count)) +
  geom_tile(color = "white") + # 白色边框区分tile
  geom_text(aes(label = count), color = "black", size = 5) + # 显示计数数值
  scale_fill_gradient(low = "white", high = "steelblue") + # 颜色渐变
  labs(title = "Group Shared Observations Count", x = "Group", y = "Group") +
  theme_minimal()

如果想用Base R的热力图工具,可以用gplots包的heatmap.2:

library(gplots)
heatmap.2(shared_matrix_base, 
          cellnote = shared_matrix_base, # 显示每个tile的计数
          notecol = "black",
          col = colorRampPalette(c("white", "steelblue"))(100),
          trace = "none", # 关闭不必要的线条
          dendrogram = "none", # 不需要聚类树
          main = "Group Shared Observations Count",
          xlab = "Group", ylab = "Group")

为什么你的之前代码不符合需求?

你之前的代码是筛选出被至少两个组共享的观测,然后直接绘制观测×组的交叉表,这展示的是哪些观测被哪些组共享,而不是组与组之间共享了多少观测。我们的方案是先计算组对的共享计数,再可视化这个计数矩阵,完全匹配你的需求。

内容的提问来源于stack exchange,提问作者user964689

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 12:57:30