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

R语言利用有限匹配字符按配对站点筛选数据行方法

R语言筛选配对站点before/after对应行

需求描述

提取数据中满足配对规则的行:同一行的两个位置列中,一列带事件前标识before、另一列带事件后标识after,且两列对应的站点、位置编号完全匹配。
给定测试数据如下,预期返回原数据的第2行、第5行:

dat <- data.frame(var1 = c('Green Island_one_before', 'Green Island_two_before', 'Green Island_one_after', 'Pink Island_one_before', 'Pink Island_two_after', 'Pink Island_five_after'),
                 var2 = c('Green Island_three_before', 'Green Island_two_after', 'Green Island_one_after', 'Pink Island_four_before', 'Pink Island_two_before', 'Pink Island_six_after'),
                 value = c(1, 7, 4, 2, 8, 3))

实现思路

核心判断逻辑分两步,逐行校验:

  • 两列字符串末尾的时间标识必须刚好是一个before、一个after,不存在两个同是before/同是after的情况
  • 去掉末尾时间标识后,两列剩下的「站点名+位置编号」部分必须完全一致,代表是同一个点位的前后配对

代码方案

基础R实现(无需安装额外包)

# 定义拆分函数:分离位置前缀、时间标识
split_str <- function(col) {
  prefix <- sub("_(before|after)$", "", col)
  tag <- sub(".*_", "", col)
  list(prefix = prefix, tag = tag)
}

v1 <- split_str(dat$var1)
v2 <- split_str(dat$var2)

# 按条件筛选
result <- dat[
  ((v1$tag == "before" & v2$tag == "after") | (v1$tag == "after" & v2$tag == "before")) &
  v1$prefix == v2$prefix,
]

运行后输出结果和预期完全一致:

> result
                    var1                    var2 value
2 Green Island_two_before  Green Island_two_after     7
5  Pink Island_two_after Pink Island_two_before     8

tidyverse实现

如果日常用tidyverse流处理数据,也可以用以下写法:

library(dplyr)
library(tidyr)

result <- dat %>%
  mutate(rowid = row_number()) %>%
  pivot_longer(c(var1, var2), values_to = "str") %>%
  separate(str, into = c("loc", "tag"), sep = "_(?=(before|after)$)") %>%
  group_by(rowid) %>%
  filter(n_distinct(tag) == 2, n_distinct(loc) == 1) %>%
  ungroup() %>%
  distinct(rowid, value) %>%
  left_join(dat, by = c("rowid", "value")) %>%
  select(-rowid)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 06:12:12