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

R语言dplyr如何正确设置Mutate选项提取行内第二个匹配字段

问题原因

你的代码存在两个核心问题,导致无法得到正确结果:

  1. 正则匹配规则不符合var2的特征:var2的取值是newyork 6/newyork7/newyork8这类开头为字母、内容包含数字的字符串,你之前用的str_detect(.x, "^\\d")仅能匹配开头为数字的字符串,完全捕获不到var2对应的值。
  2. 第二个值的提取逻辑错误:三行数据中第一个以数字开头的地址(即var1)所在列并不固定(第一行在col2、第二行在col3、第三行在col4),你固定从col3开始向后查找非NA值,会把第二行col3的var1值错当成var2,无法实现「逐行取第二个符合条件值」的需求。
    另外你数据里的缺失值是字符串类型的"NA",不是R语言原生识别的NA类型,coalesce函数会把它当成普通字符串处理,也会干扰匹配结果。
修正代码

推荐用逐行处理的方案,逻辑最清晰,后续扩展也方便,不需要拆分多个步骤:

library(tidyverse)

desired_result <- sample_data %>%
  rowwise() %>%
  mutate(
    # 逐行提取col2到col5中,不等于"NA"、且包含数字的所有值,按原列顺序存储
    match_set = c_across(col2:col5)[. != "NA" & str_detect(., "\\d")],
    var1 = match_set[1],
    var2 = match_set[2]
  ) %>%
  select(col1, var1, var2) %>%
  ungroup()

运行后得到的结果和你给出的目标格式完全一致:

# A tibble: 3 × 3
  col1  var1              var2     
  <chr> <chr>             <chr>    
1 james 123 forest road   newyork 6
2 john  124 valley street newyork7 
3 henry 125 ocean road    newyork8

如果你要沿用之前coalesce的写法,需要先把字符串"NA"转成原生NA,提取完var1后,把每行var1对应的单元格替换为NA,再做第二次匹配,注意修正var2的匹配正则:

library(tidyverse)

# 先把字符串"NA"转成R可识别的缺失值
clean_data <- sample_data %>%
  mutate(across(col2:col5, ~na_if(.x, "NA")))

result <- clean_data %>%
  # 提取第一个开头为数字的值var1
  mutate(
    across(col2:col5, ~case_when(str_starts(.x, "\\d") ~ .x, TRUE ~ NA_character_)),
    var1 = coalesce(col2, col3, col4, col5)
  ) %>%
  # 移除已匹配的var1,提取第二个包含数字的值var2
  mutate(
    across(col2:col5, ~case_when(. == var1 ~ NA_character_,
                                 str_detect(.x, "\\d") ~ .x,
                                 TRUE ~ NA_character_)),
    var2 = coalesce(col2, col3, col4, col5)
  ) %>%
  select(col1, var1, var2)

这个写法同样可以得到正确结果,但灵活性较差,如果后续需要提取第3、第4个匹配值,需要重复写多轮替换逻辑,不如逐行提取的方案简洁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 16:54:20