使用dplyr移除数据列字符串中无关个体并清除空引号痕迹
问题
我有一个记录个体观测数据的数据集,individuals列中有时会混入无明确组属的个体。我希望移除这些个体,但使用现有方法后,原位置会留下空引号"",需要实现移除无关个体且不留下空引号痕迹的处理。
各组所属个体定义:
groupA = c("Noir", "Bleue", "Rouge") groupB = c("Dion", "Saphir", "Chapman") groupC= c("Murray", "Nile", "Mississippi")
正常数据示例:
group date time individuals A 1/1/2016 9:00 "Noir", "Bleue", "Rouge" B 1/1/2016 9:00 "Dion", "Saphir", "Chapman" C 1/1/2016 9:00 "Murray", "Nile", "Mississippi"
混入无关个体的数据示例(InconnuA、InconnuB、Inconnu1为无组属个体):
group date time individuals A 2/1/2016 9:00 "Noir", "Bleue", "InconnuA" B 2/1/2016 9:00 "Dion", "Saphir", "InconnuB" C 2/1/2016 9:00 "Murray", "Nile", "Inconnu1"
我使用以下代码移除个体,但结果中出现了空引号:
IndividualsRemoved <- partycompfocal_GroupingID %>% mutate(across("individuals", str_replace, "InconnuA", ""), across("individuals", str_replace, "InconnuB", ""), across("individuals", str_replace, "Inconnu1", ""), across("individuals", str_replace, "Inconnu2", ""), across("individuals", str_replace, "Inconnu3", ""), )
处理后的数据结果:
group date time individuals A 2/1/2016 9:00 "Noir", "Bleue", "" B 2/1/2016 9:00 "Dion", "Saphir", "" C 2/1/2016 9:00 "Murray", "Nile", ""
期望得到的最终结果:
group date time individuals A 2/1/2016 9:00 "Noir", "Bleue" B 2/1/2016 9:00 "Dion", "Saphir" C 2/1/2016 9:00 "Murray", "Nile"
解决方案
之前用str_replace直接替换为空字符串,只会删除目标个体的内容,但保留了引号和前后的逗号,导致空引号残留。下面提供两种可行的解决方法:
方法一:按组筛选合法个体(更严谨)
利用group列的值匹配对应组的合法个体列表,拆分字符串后筛选再重新拼接,彻底去掉无关个体:
library(dplyr) library(stringr) # 把各组整合为列表,方便按组匹配 group_list <- list( A = groupA, B = groupB, C = groupC ) IndividualsRemoved <- partycompfocal_GroupingID %>% rowwise() %>% mutate( # 拆分individuals列:去掉引号,按逗号+空格分割为单个个体 indiv_list = str_split(str_remove_all(individuals, '"'), ",\\s*")[[1]], # 根据当前group筛选属于该组的合法个体 valid_indiv = list(intersect(indiv_list, group_list[[group]])), # 重新拼接成带引号的标准格式 individuals = if(length(valid_indiv) > 0) { str_c('"', str_c(valid_indiv, collapse = '", "'), '"') } else { "" # 无合法个体时留空,可按需调整 } ) %>% ungroup() %>% select(-indiv_list, -valid_indiv) # 删除中间辅助列
方法二:正则匹配删除无关个体(更快捷)
如果已知所有无关个体以Inconnu开头,可以用正则匹配整个带引号的无关个体,同时处理残留的逗号:
library(dplyr) library(stringr) IndividualsRemoved <- partycompfocal_GroupingID %>% mutate( # 匹配带引号的Inconnu开头个体,包含前后可能的逗号和空格 individuals = str_replace_all(individuals, '(,\\s*)?"Inconnu[^"]+"(,\\s*)?', function(match) { # 处理替换后多余的逗号:去掉开头或结尾的逗号+空格 str_remove_all(match, '(^,\\s*)|(,\\s*$)') }), # 清理开头/结尾可能残留的逗号 individuals = str_trim(str_remove_all(individuals, '^,|,$'), whitespace = ",\\s*") )
两种方法对比
- 方法一:基于合法个体列表筛选,不管无关个体叫什么,只要不在合法列表里都会被移除,适合后续可能新增无关个体的场景。
- 方法二:依赖无关个体的命名规则,处理速度更快,但如果无关个体命名不统一,可能出现漏处理。
内容的提问来源于stack exchange,提问作者MIGUEL
相关产品推荐
相关产品推荐

