R数据框中为i=j及对称i≠j事件分配唯一ID的方法咨询
实现对称分组唯一ID分配的R代码方案
核心处理逻辑是为每对(i,j)生成统一的分组标识:将两个字符按固定顺序拼接,保证(a,b)和(b,a)生成的标识完全相同,再对不同的标识按首次出现顺序分配编号即可。
基础R实现版本
首先运行示例数据生成代码:
set.seed(5) df <- data.frame(year=rep(c(2010:2011), each=8), i=rep(c('66','66','6','6','65','65','6','6'), times=2), j=rep(c('66','6','66','6','65','6','65','6'), times=2), count=round(runif(8, 0, 5),0))
分组分配ID的处理代码:
# 生成统一分组键:对i、j排序后拼接,保证(i,j)和(j,i)的键一致 df$group_key <- apply(df[, c("i", "j")], 1, function(x) paste(sort(x), collapse = "_")) # 先给i=j的行统一赋值为0 df$group_id <- ifelse(df$i == df$j, "0", NA) # 提取i≠j的唯一分组键,按首次出现顺序分配1及以上的编号 unique_keys <- unique(df$group_key[df$i != df$j]) key_map <- setNames(as.character(seq_along(unique_keys)), unique_keys) # 把编号匹配回原数据 df$group_id[is.na(df$group_id)] <- key_map[df$group_key[is.na(df$group_id)]] # 可选:删除中间生成的辅助列group_key df$group_key <- NULL
处理后的数据完全符合要求:所有i=j的行group_id为0,66_6和6_66的group_id为1,65_6和6_65的group_id为2。
tidyverse简洁实现版本
如果习惯使用dplyr语法,可以用更高效的写法:
library(dplyr) df <- df %>% mutate( # 用pmin/pmax按数值排序拼接,比apply效率更高 group_key = paste(pmin(i,j), pmax(i,j), sep = "_"), group_id = case_when( i == j ~ "0", TRUE ~ as.character(match(group_key, unique(group_key[i != j]))) ) ) %>% select(-group_key)
内容的提问来源于stack exchange,提问作者James R.
相关产品推荐
相关产品推荐

