在R中按分组统计两列行为转移次数生成矩阵表的错误排查
问题分析与解决:按个体分组生成行为转移矩阵
你遇到的问题核心是分组上下文的引用错误,导致代码没有按id分组统计行为转移,而是计算了全局的总次数。我来帮你拆解问题并给出解决方案:
错误原因
在dplyr的分组操作中,你使用了df$behav1和df$behav2这种绝对引用方式——这会直接调用原始数据框的整列数据,完全绕过了group_by(id)创建的分组上下文。所以table(df$behav1, df$behav2)计算的是所有个体的行为转移总和,而非每个分组内的统计结果。
修正方案
方案1:保留矩阵格式的分组统计
使用dplyr的分组上下文直接引用列名,并用list()存储每个组的转移矩阵(避免summarise自动拆分矩阵列):
library(dplyr) # 先修正原始数据框的笔误 id<- c("1", "1", "1", "1", "2", "2", "2", "2", "3", "3", "3", "3") behav1<- c("A", "C", "C", "B", "C", "C", "A", "A", "A", "B", "B", "A") behav2<- c("C", "A", "A", "B", "A", "B", "A", "B", "C", "B", "B", "C") df <- data.frame(id, behav1, behav2) # 按id分组生成转移矩阵 result <- df %>% group_by(id) %>% summarise(转移矩阵 = list(as.data.frame.matrix(table(behav1, behav2))), .groups = "drop") # 查看结果 print(result)
运行后,每个id对应的转移矩阵列会存储该个体的行为转移计数表,比如id=1的矩阵就是:
A B C A 0 0 1 B 0 1 0 C 2 0 0
方案2:生成更易读的宽格式表
如果需要把结果展开为结构化的宽格式(每个转移路径作为列),可以结合tidyr的pivot_wider:
library(dplyr) library(tidyr) result_wide <- df %>% group_by(id, behav1, behav2) %>% count(name = "转移次数") %>% pivot_wider( names_from = behav2, values_from = 转移次数, values_fill = 0, # 缺失的转移路径填充0 names_prefix = "到" # 给列名添加前缀,更清晰 ) print(result_wide)
输出示例(id=1的行):
id behav1 到A 到B 到C <chr> <chr> <int> <int> <int> 1 1 A 0 0 1 2 1 B 0 1 0 3 1 C 2 0 0
关键总结
在dplyr分组操作中,永远直接使用列名(不要加数据框$前缀),这样才能让函数识别当前分组的子集数据,实现真正的分组统计。
内容的提问来源于stack exchange,提问作者Astor
相关产品推荐
相关产品推荐

