如何在平行列中向前查找下一个匹配项(R语言tidyverse)
在tidyverse中实现"按to值向下匹配from对应type"的简便方法
需求说明
给数据框新增want列:对每一行,根据当前行to列的值,在from列中向下查找第一个出现该值的行,将该行的type值作为当前行的want;若后续无匹配项,want设为NA。
示例数据
示例1(含预期结果)
library(tidyverse) d <- tribble(~from, ~to, ~type, ~want, "a", "b", 9, 8, "b", "c", 8, 0, "a", "x", 6, 7, "c", "d", 0, 3, "c", "d", 5, 3, "x", "y", 7, NA, "d", "e", 3, 4, "e", "f", 4, 5, "e", "f", 2, 5, "e", "f", 8, 5, "f", "g", 5, NA)
示例2
d2 <- tribble(~from, ~to, ~type, "a", "b", 0, "b", "a", 1, "a", "c", 2)
简便实现方法
用dplyr搭配purrr::map_dbl就能快速搞定,核心思路是对每行的to值,从当前行的下一行开始找from匹配的记录,取第一个对应的type值:
# 处理示例1 d_result <- d %>% mutate(want_calc = map_dbl(to, function(target) { # 获取当前行之后的所有行数据 after_rows <- slice(., (row_number() + 1):n()) # 筛选from等于target的行,取第一个type first_match <- after_rows$type[after_rows$from == target][1] # 无匹配则返回NA ifelse(is.null(first_match), NA_real_, first_match) })) # 验证计算结果与预期是否一致 all.equal(d_result$want_calc, d$want) # [1] TRUE
处理示例2
直接复用相同逻辑:
d2_result <- d2 %>% mutate(want = map_dbl(to, function(target) { after_rows <- slice(., (row_number() + 1):n()) first_match <- after_rows$type[after_rows$from == target][1] ifelse(is.null(first_match), NA_real_, first_match) })) # 输出结果 d2_result # # A tibble: 3 × 4 # from to type want # <chr> <chr> <dbl> <dbl> # 1 a b 0 1 # 2 b a 1 2 # 3 a c 2 NA
补充说明
- 该方法逻辑直观,无需额外创建辅助表,适合中小规模数据集;
- 若数据集较大,可先按
from分组记录行号,再用连接+筛选的方式优化性能(避免逐行遍历)。
内容的提问来源于stack exchange,提问作者r.user.05apr
相关产品推荐
相关产品推荐

