在dplyr中筛选prod列值存在于lob列中的数据行
解决R数据框筛选:保留prod值存在于lob分号分隔字符串中的行
嘿,我来帮你搞定这个数据筛选的问题!你需要保留那些prod列的值出现在对应行lob列(分号分隔字符串)里的记录,我给你两种可行的方法,一起来看看:
首先,确认原始数据
先把你提供的可复现代码放出来,确保我们用的是同一个数据集:
df <- data.frame(prod = c("CES", "Access", "Access", "CES"), lob = c("Access;Entertainment", "CES", "Access", "Access;Entertainment;CES"), stringsAsFactors = FALSE) # 建议设置stringsAsFactors=FALSE,避免因子类型带来的问题
原始数据输出如下:
prod lob 1 CES Access;Entertainment 2 Access CES 3 Access Access 4 CES Access;Entertainment;CES
方法1:使用tidyverse工具(dplyr + stringr)
这种方法更直观,适合熟悉tidyverse风格的用户:
library(tidyverse) result <- df %>% rowwise() %>% # 开启逐行处理模式 filter(prod %in% str_split(lob, ";")[[1]]) %>% # 拆分lob为向量,检查prod是否在其中 ungroup() # 取消行分组,恢复常规数据框格式 # 查看结果 print(result)
输出正好是你想要的期望结果:
# A tibble: 2 × 2 prod lob <chr> <chr> 1 Access Access 2 CES Access;Entertainment;CES
代码解释:
rowwise():让后续函数按每一行独立处理,而非默认的按列批量处理str_split(lob, ";")[[1]]:把当前行的lob字符串按分号拆分成字符向量,[[1]]用来提取列表中的向量元素prod %in% ...:判断当前行的prod值是否存在于拆分后的向量中,filter()只保留返回TRUE的行
方法2:使用Base R实现
如果不想加载额外包,用Base R也能轻松解决:
# 先把每个lob字符串拆分成列表 df$lob_elements <- strsplit(df$lob, ";") # 逐行检查prod是否在对应的lob_elements中,筛选符合条件的行 result_base <- df[sapply(seq_along(df$lob_elements), function(i) df$prod[i] %in% df$lob_elements[[i]]), ] # 去掉临时添加的lob_elements列 result_base <- result_base[, -3] # 查看结果 print(result_base)
输出和方法1完全一致:
prod lob 3 Access Access 4 CES Access;Entertainment;CES
代码解释:
strsplit(df$lob, ";"):把整个lob列拆分成一个列表,每个元素是对应行的分号拆分结果sapply(seq_along(...), function(i)...):遍历每一行的索引,检查对应行的prod值是否在该行的lob拆分向量中,返回逻辑筛选向量- 用逻辑向量
df[逻辑向量, ]筛选出符合条件的行,最后去掉临时列
为什么之前拆分没解决?
你提到拆分lob列为向量/列表没解决问题,大概率是因为没有逐行对应检查prod和拆分后的lob元素。比如直接把lob拆分成多列,没法直接关联到同一行的prod值;而上面两种方法都确保了每一行的prod只和当前行拆分后的lob元素做匹配,这样就准确筛选出了你要的结果。
内容的提问来源于stack exchange,提问作者Matt W.
相关产品推荐
相关产品推荐

