如何检测数据框列中是否存在不在Codebook内的未知代码
检查分号分隔代码中是否存在未收录的代码
你可以通过拆分代码列→逐个验证→判断是否存在未收录项的思路解决这个问题,用tidyverse的实现如下:
完整代码
library(tidyverse) # 示例数据 AppliedCodes <- c("AAAA; BBBB; CCCC;", "CCCC; FFFF; GGGG", "AAAA; DDD; EEEE") df <- data.frame(AppliedCodes) Codebook <- c("AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF") # 处理逻辑 df2 <- df %>% mutate( # 拆分代码:按分号+任意空格分割,过滤空字符串(处理末尾分号的情况) split_codes = str_split(AppliedCodes, ";\\s*") %>% map(~ .x[.x != ""]), # 检查是否存在不在Codebook中的代码,转换为Yes/No标记 UnknownCode = if_else(map_lgl(split_codes, ~ any(!.x %in% Codebook)), "Yes", "No"), # 移除中间辅助列(可选) split_codes = NULL ) # 查看结果 print(df2)
输出结果
AppliedCodes UnknownCode 1 AAAA; BBBB; CCCC; No 2 CCCC; FFFF; GGGG No 3 AAAA; DDD; EEEE Yes
关键步骤说明
- 拆分代码:用
str_split(AppliedCodes, ";\\s*")处理分号和后续空格的组合,再通过map(~ .x[.x != ""])过滤拆分后产生的空字符串(比如第一行末尾的分号会生成空元素)。 - 验证未收录项:
map_lgl(split_codes, ~ any(!.x %in% Codebook))对每个拆分后的代码列表,检查是否存在任意一个不在Codebook中的代码,返回逻辑值。 - 转换标记:用
if_else把逻辑值转为你需要的"Yes"/"No"格式。
为什么之前的方法不适用
你之前用str_detect拼接Codebook的方式,本质是检查「是否存在至少一个在Codebook中的代码」,只要有一个代码匹配就返回TRUE,无法检测「是否存在不在Codebook中的代码」。而拆分后逐个验证的思路,正好解决了这个逻辑反转的问题。
内容的提问来源于stack exchange,提问作者Jan
相关产品推荐
相关产品推荐

