You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用qdapRegex的rm_between在mutate中提取字符串失败,求原因

问题原因分析

你的问题核心出在对rm_between返回值的索引方式和dplyr的向量化操作逻辑上,具体来说:

  1. 当你把rm_between作用于整个Values向量时,它返回的是一个长度等于数据框行数的列表:

    • 对于第1、2行没有"Height : "的字符串,对应的列表元素是空的list()
    • 第3行匹配成功,对应的列表元素是list("13")
  2. 你写的rm_between(...)[[1]]是直接取这个大列表的第一个元素(也就是第1行的空列表),而不是对每个列表元素单独提取第一个值。所以当if_else判断第3行满足条件时,它会把这个空列表的[[1]](也就是NULL,在数据框中显示为<NA>)赋值给该行,而前两行的"None"是字符型,最终就出现了第三行显示<NA>的情况。

解决方法

这里有两种更靠谱的处理方式:

方法一:用purrr逐元素处理rm_between的返回列表

我们可以用purrr::map_chr遍历rm_between返回的列表,对每个元素提取第一个值(如果有的话),没有的话返回NA_character_,再用coalesce把NA替换成"None":

library(dplyr)
library(qdapRegex)
library(purrr)

# 重新创建测试数据框
ID <- c("1","2","3")
Values <- c("A","B","Height : 13cm Width : 14cm")
dfTest <- data.frame(ID,Values)

# 正确处理
dfTest <- dfTest %>% 
  mutate(
    # 先提取每个行的匹配结果,没有则返回NA
    Height_temp = map_chr(rm_between(Values, "Height : ", "cm", extract = TRUE),
                         ~if (length(.x) > 0) .x[[1]] else NA_character_),
    # 把NA替换成"None"
    Height = coalesce(Height_temp, "None")
  ) %>%
  select(-Height_temp) # 删掉临时列

运行后你会得到预期结果:

ID                          Values Height
1  1                              A   None
2  2                              B   None
3  3 Height : 13cm Width : 14cm    13

方法二:用stringr::str_extract更简洁处理

如果你的匹配规则比较固定(就是提取"Height : "和"cm"之间的数字),用stringr包的str_extract会更直接,不需要处理列表:

library(dplyr)
library(stringr)

dfTest <- dfTest %>% 
  mutate(Height = if_else(
    str_detect(Values, "Height : "),
    # 用正则正向预查提取中间的数字
    str_extract(Values, "(?<=Height : )\\d+(?=cm)"),
    "None"
  ))

这个正则表达式(?<=Height : )\\d+(?=cm)的意思是:匹配前面是"Height : "、后面是"cm"的连续数字,完美提取你想要的"13"。

内容的提问来源于stack exchange,提问作者BroQ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:23:35