如何将单值数据转换为二元(关系型)数据?R语言实操求助
问题描述
现有按conflict_ID排序的冲突数据,格式如下:
conflict_ID country_code 1 1 1 2 1 3 2 1 3 31 2 50 3 3
需要将其转换为二元配对数据,最终得到如下格式:
conflict_ID country_code_1 country_code_2 1 1 2 1 1 3 1 2 3 2 1 50 3 3 31
尝试了以下代码但无法得到预期结果,请求指点:
mydf %>% group_by(conflict_ID) %>% mutate(ind= paste0('country_code', row_number())) %>% spread(ind, country_code)
解决方案
你用的这段代码是把每个冲突组里的国家转成宽格式(一行展示该组所有国家),但你要的是组内国家的所有二元无序配对,得换个思路来实现:
方法1:用dplyr + tidyr实现
library(dplyr) library(tidyr) mydf %>% group_by(conflict_ID) %>% summarise( # 生成每组里所有两两配对的列表 country_pairs = list(combn(country_code, 2, simplify = FALSE)) ) %>% # 把列表拆成单独的行 unnest(country_pairs) %>% # 将配对拆分到两列中 mutate( country_code_1 = country_pairs[[1]], country_code_2 = country_pairs[[2]] ) %>% # 删掉临时用的配对列 select(-country_pairs) %>% # 按conflict_ID排序,和你要的格式对齐 arrange(conflict_ID)
方法2:用data.table实现(适合大数据场景)
library(data.table) setDT(mydf)[, .( country_pairs = transpose(combn(country_code, 2, simplify = FALSE)) ), by = conflict_ID][, .(country_code_1 = V1, country_code_2 = V2), by = conflict_ID ]
原代码问题说明
你的原代码逻辑是给每个组内的国家按行号加后缀,再转成宽表,最终输出会是这样:
conflict_ID country_code1 country_code2 country_code3 1 1 2 3 2 1 50 NA 3 31 3 NA
这和你需要的两两组合拆分行完全是两种数据结构,所以达不到你想要的效果。
内容的提问来源于stack exchange,提问作者craszer
相关产品推荐
相关产品推荐

