如何在R中将数据框转换为网络分析用的长格式列联表
解决方案:将情绪共现数据转换为两两组合计数
需求分析
需要将宽格式的个体情绪存在数据,转换为所有无序情绪两两组合的共现次数(包括共现次数为0的组合)。
步骤1:准备环境与数据
首先加载tidyverse包(未安装的话先运行install.packages("tidyverse")),再定义原始数据:
# 安装并加载tidyverse(仅首次运行需要安装) # install.packages("tidyverse") library(tidyverse) # 原始数据 id <- c(1:4) happy <- c(1,0,1,0) sad <- c(0,0,0,1) angry <- c(0,1,0,0) excited <- c(1,0,1,1) emot <- data.frame(id, happy, sad, angry, excited)
步骤2:转换为长格式(仅保留存在的情绪)
把宽格式的情绪列转换为每行对应一个个体的一个存在情绪:
emot_long <- emot %>% pivot_longer(cols = -id, names_to = "emotion", values_to = "present") %>% filter(present == 1) %>% # 只保留提到该情绪的行 select(-present)
转换后的数据结构示例:
| id | emotion |
|---|---|
| 1 | happy |
| 1 | excited |
| 2 | angry |
| 3 | happy |
| 3 | excited |
| 4 | sad |
| 4 | excited |
步骤3:生成个体内的情绪两两组合
对每个个体,生成其所有情绪的无序两两组合(避免重复统计happy-excited和excited-happy):
emot_pairs <- emot_long %>% group_by(id) %>% summarize( # 对有2种及以上情绪的个体生成两两组合,否则返回空 pairs = if(n() >= 2) list(combn(emotion, 2, simplify = FALSE)) else list(NULL) ) %>% unnest(pairs) %>% # 展开组合列表 mutate( source = map_chr(pairs, ~.[1]), # 提取组合第一个元素 target = map_chr(pairs, ~.[2]) # 提取组合第二个元素 ) %>% select(-pairs)
步骤4:统计次数并补全所有组合
先生成所有可能的情绪两两组合,再与统计结果合并,补全次数为0的组合:
# 获取所有情绪名称 emotions <- colnames(emot)[-1] # 生成所有无序两两组合 all_pairs <- combn(emotions, 2, simplify = FALSE) %>% map_dfr(~tibble(source = .[1], target = .[2])) # 统计次数并补全0值 result <- emot_pairs %>% count(source, target, name = "count") %>% right_join(all_pairs, by = c("source", "target")) %>% mutate(count = replace_na(count, 0)) %>% # 将NA替换为0 arrange(source, target)
最终结果
运行print(result)即可得到需求格式:
print(result) # source target count # 1 happy sad 0 # 2 happy angry 0 # 3 happy excited 2 # 4 sad angry 0 # 5 sad excited 1 # 6 angry excited 0
内容的提问来源于stack exchange,提问作者Sointu
相关产品推荐
相关产品推荐

