如何用tidyverse/dplyr筛选name_1与name_2的唯一组合(不隔行取子集)
问题
给定如下R数据:
structure(list(name_1 = c("Kevin", "Tom", "Laura", "Julie"), name_2 = c("Tom", "Kevin", "Julie", "Laura"), value = c(10, 10, 20, 20)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -4L))
其 tibble 形式为:
# A tibble: 4 × 3 name_1 name_2 value <chr> <chr> <dbl> 1 Kevin Tom 10 2 Tom Kevin 10 3 Laura Julie 20 4 Julie Laura 20
需要不通过隔行取子集的方式,筛选出name_1和name_2的唯一组合,优先使用tidyverse/dplyr方法,期望输出:
# A tibble: 2 × 3 name_1 name_2 value <chr> <chr> <dbl> 1 Kevin Tom 10 2 Laura Julie 20
解决方案
使用dplyr可以通过生成统一的组合标识来实现去重,代码如下:
library(dplyr) df %>% rowwise() %>% # 生成排序后的名字组合字符串,作为重复标识 mutate(sorted_pair = paste(sort(c(name_1, name_2)), collapse = "-")) %>% ungroup() %>% # 根据标识去重,保留整行数据 distinct(sorted_pair, .keep_all = TRUE) %>% # 删除临时标识列 select(-sorted_pair)
步骤说明:
rowwise():开启按行处理模式,确保每行的名字单独排序mutate(...):将每行的两个名字按字母排序后拼接成字符串,比如"Tom-Kevin"会变成"Kevin-Tom",这样互为颠倒的组合会得到相同的标识ungroup():取消行分组,回到常规数据框处理模式distinct(...):根据生成的标识列去重,.keep_all = TRUE保证保留所有原始列select(-sorted_pair):移除临时生成的标识列,得到目标结果
内容的提问来源于stack exchange,提问作者HoelR
相关产品推荐
相关产品推荐

