R语言中使用unnest时如何避免重复行并处理str_extract_all返回的character(0)问题
解决str_extract_all后避免重复行并合并匹配结果的问题
我完全懂你遇到的麻烦:用str_extract_all要么拿到character(0)没法正常处理,要么用unnest会生成重复行,还得同时把多个匹配结果合并成逗号分隔的字符串,还要保留每个匹配的单独列。下面直接给你可行的解决方案:
完整代码实现
library(dplyr) library(stringr) library(tidyr) # 先构造你的数据框 x <- tibble( V1 = c("E_R4B, E_Y6A, U_5T", "A_R4B, B_Y6A, U_5T") ) # 处理流程 x_final <- x %>% # 提取所有符合模式的字符串,得到列表列(空匹配会返回character(0)) mutate(matches = str_extract_all(V1, "E_([A-Z0-9])+")) %>% # 将列表列拆分为单独的列,空匹配自动填充NA unnest_wider(matches, names_sep = "_") %>% # 按行合并拆分后的列,生成逗号分隔的字符串,同时处理全NA的情况 rowwise() %>% mutate(V3 = str_c(c(matches_1, matches_2), collapse = ",", na.rm = TRUE)) %>% # 如果合并后是空字符串,转为NA(对应没有匹配的情况) mutate(V3 = ifelse(V3 == "", NA_character_, V3)) %>% ungroup() %>% # 重命名列以匹配你的期望输出 rename(V2 = matches_1, V2_2 = matches_2) %>% # 调整列顺序 select(V1, V2, V2_2, V3) # 查看结果 print(x_final)
输出结果
# A tibble: 2 × 4 V1 V2 V2_2 V3 <chr> <chr> <chr> <chr> 1 E_R4B, E_Y6A, U_5T E_R4B E_Y6A E_R4B,E_Y6A 2 A_R4B, B_Y6A, U_5T NA NA NA
关键步骤解释
- 用列表列存储匹配结果:
str_extract_all默认返回列表,这样可以保留每行的所有匹配项,不会直接拆分行。 - 拆分为单独列:
unnest_wider会把列表中的每个元素拆成单独的列,空列表(也就是没有匹配的行)会自动填充NA,完美解决character(0)的问题。 - 合并列生成逗号分隔字符串:用
rowwise()按行处理,str_c合并非NA的匹配项,再把空字符串转为NA,确保没有匹配的行显示NA而不是空串。
另一种处理simplify=T结果的方法
如果你更习惯用simplify=T得到矩阵列,也可以这样处理:
x <- tibble( V1 = c("E_R4B, E_Y6A, U_5T", "A_R4B, B_Y6A, U_5T") ) # 提取为矩阵列 x$matches_mat <- str_extract_all(x$V1, "E_([A-Z0-9])+", simplify = TRUE) # 拆分为单独列 x <- cbind(x, as.data.frame(x$matches_mat)) %>% rename(V2 = V1, V2_2 = V2) %>% select(-matches_mat) # 合并生成V3列 x <- x %>% rowwise() %>% mutate(V3 = str_c(c(V2, V2_2), collapse = ",", na.rm = TRUE)) %>% mutate(V3 = ifelse(V3 == "", NA_character_, V3)) %>% ungroup()
这样也能得到和上面一致的结果,看你更喜欢哪种风格。
内容的提问来源于stack exchange,提问作者Nnnz
相关产品推荐
相关产品推荐

