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

如何将单值数据转换为二元(关系型)数据?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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 04:30:55