使用map_df()处理字符串时观测值消失,如何排查解决?
问题描述
编辑致歉:深夜提问导致问题质量欠佳。
我尝试使用map_df()将字符字符串映射到列中,列已创建但无观测值。代码如下:
a <- "Master Dev: ABC" b <- "Developer: 123" c <- "Contractor: XYZ" d <- "Financer: 789" list <- list(a,b,c,d) list %>% map_df(~list(Master = .x %>% str_subset(.,"Master Dev: ") %>% sub(".*Master Dev: ","",.), Architect = .x %>% str_subset(.,"Architect: ") %>% sub(".*Architect: ","",.), Contractor = .x %>% str_subset(.,"Contractor: ") %>% sub(".*Contractor: ","",.), Financer = .x %>% str_subset(.,"Financer: ") %>% sub(".*Financer: ","",.) ) ) ->dF
代码位于循环中,每次迭代可能包含a、b、c、d中的任意标题组合,预期输出是将冒号后的信息拆分到对应列的数据框,如下表:
| Master Dev | Developer | Contractor | Financer |
|---|---|---|---|
| ABC | |||
| 123 | |||
| XYZ | |||
| 789 |
我确认str_subset()和sub()功能正常,因为以下测试能正确解析出对应名称:
list %>% str_subset(.,"Master Dev: ") %>% sub(".*Master Dev: ","",.)
请问我忽略了什么问题?
问题原因
你的代码里,str_subset()作用在单个字符串时,不匹配的情况会返回长度为0的空向量,后续sub()处理空向量仍返回空向量。map_df()组合这些list成数据框时,空向量会被识别为缺失元素,导致无法生成正确的观测值。另外,你定义的列名(比如Master)和预期的Master Dev不匹配,还多了一个不需要的Architect列。
解决方法
直接用str_extract()结合正则表达式提取目标内容,不匹配时返回空字符串,同时修正列名与预期一致:
library(tidyverse) a <- "Master Dev: ABC" b <- "Developer: 123" c <- "Contractor: XYZ" d <- "Financer: 789" my_list <- list(a,b,c,d) # 避免用`list`作为变量名,和内置函数冲突 my_list %>% map_df(~list( `Master Dev` = str_extract(.x, "(?<=Master Dev: ).*") %||% "", Developer = str_extract(.x, "(?<=Developer: ).*") %||% "", Contractor = str_extract(.x, "(?<=Contractor: ).*") %||% "", Financer = str_extract(.x, "(?<=Financer: ).*") %||% "" )) -> dF
运行后得到的结果与预期完全一致:
# A tibble: 4 × 4 `Master Dev` Developer Contractor Financer <chr> <chr> <chr> <chr> 1 ABC "" "" "" 2 "" 123 "" "" 3 "" "" XYZ "" 4 "" "" "" 789
补充说明
str_extract()的正则表达式(?<=...)是正向预查,直接匹配冒号后的内容,无需先筛选再替换;%||%是rlang包的函数,用来把匹配失败返回的NA替换成空字符串,确保每个位置都有有效内容;- 避免用
list作为变量名,防止和R内置的list()函数冲突引发错误。
内容的提问来源于stack exchange,提问作者Bart Yarborough
相关产品推荐
相关产品推荐

