使用str_locate处理DataFrame多行列时结果异常的问题排查
多行DataFrame中
str_locate_all匹配\r返回空的原因及解决方法 首先重现问题场景:
library(tidyverse) df <- structure(list(tasks = c("xxx<br>Mitte<br>- Niedersachsen, <br><br><br>", "xxx – Jahrgang 2022<br>\r<br>Mein")), class = "data.frame", row.names = c(NA, -2L))
当运行以下代码处理多行DataFrame时,position_r列结果为空:
df |> mutate(position_tab = list(str_locate_all(tasks, "[\t]")[[1]][,"start"]), position_n = list(str_locate_all(tasks, "[\n]")[[1]][,"start"]), position_r = list(str_locate_all(tasks, "[\r]")[[1]][,"start"]))
但仅保留第二行时,position_r能得到正确结果24:
df |> slice(2) |> mutate(position_tab = list(str_locate_all(tasks, "[\t]")[[1]][,"start"]), position_n = list(str_locate_all(tasks, "[\n]")[[1]][,"start"]), position_r = list(str_locate_all(tasks, "[\r]")[[1]][,"start"]))
核心原因
问题出在[[1]]的使用逻辑上:
- 处理多行DataFrame时,
str_locate_all(tasks, "[\r]")返回的是长度等于行数的列表,每个元素对应一行的匹配结果。 - 直接用
[[1]]提取的是这个列表的第一个元素(即第一行的匹配结果),而第一行字符串中没有\r字符,得到空向量后被重复赋值给所有行的position_r列。 - 处理单行DataFrame时,
str_locate_all返回的列表只有一个元素(对应唯一一行的结果),[[1]]刚好取到正确的匹配结果,因此能返回正确位置。
解决方法
需要对tasks列的每一行单独处理,用purrr::map遍历每个字符串元素,提取对应行的匹配起始位置:
df |> mutate(position_tab = map(tasks, ~ str_locate_all(., "[\t]")[[1]][,"start"]), position_n = map(tasks, ~ str_locate_all(., "[\n]")[[1]][,"start"]), position_r = map(tasks, ~ str_locate_all(., "[\r]")[[1]][,"start"]))
运行后可得到正确结果:
tasks position_tab position_n position_r 1 xxx<br>Mitte<br>- Niedersachsen, <br><br><br> 18 integer(0) integer(0) 2 xxx – Jahrgang 2022<br>\r<br>Mein integer(0) integer(0) 24
内容的提问来源于stack exchange,提问作者deschen
相关产品推荐
相关产品推荐

