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

R语言判断向量内数值连续存在及dplyr行过滤方法

问题描述

现有基础测试代码如下:

avector <- c(1,2,3,4,5)
num1 <- 1
num2 <- 2
num3 <- 3

num1%in%avector & num2%in%avector
# 运行返回 TRUE

需要实现和上述%in%写法风格一致的判断逻辑:仅当多个指定值在目标向量中处于连续相邻位置时,才返回TRUE,预期效果:

  • num1和num2在向量中位置相邻,判断返回TRUE
  • num1和num3在向量中间隔一个值,判断返回FALSE
# 预期返回FALSE
num1%in%avector & num3%in%avector
实际使用场景

该判断逻辑需要直接嵌入dplyr的filter()函数做数据行过滤,原有仅判断值存在的过滤代码如下:

bonus_dat %>%
  filter(lower %in% strata[[1]] & upper %in% strata[[1]])

之前尝试的位置差判断代码未得到预期结果,失败代码如下:

bonus_dat %>%
  filter((lower %in% strata[[1]] & upper %in% strata[[1]] & (( which(strata[[1]] == lower) - which(strata[[1]] == upper)) == 1)  ))

优先提供可直接用于dplyr行过滤场景的可用方案。

测试数据集

可直接运行以下代码加载测试数据:

library(dplyr)
bonus_dat <- structure(list(strata = list(c(0, 25, 100, 500, 1000, 1e+06), 
    c(0, 25, 100, 500, 1000, 1e+06), c(0, 25, 100, 500, 1000, 
    1e+06), c(0, 25, 100, 500, 1000, 1e+06), c(0, 25, 100, 500, 
    1000, 1e+06), c(0, 25, 100, 500, 1000, 1e+06)), lower = c(0L, 
25L, 100L, 500L, 500L, 1000L), upper = c(25L, 100L, 500L, 1000L, 
1000000L, 1000000L), value = c(1,3,4,6,2,1)), class = c("grouped_df", "tbl_df", 
"tbl", "data.frame"), row.names = c(NA, -6L), groups = structure(list(
    upper = c(25L, 100L, 500L, 1000L, 1000000L), .rows = structure(list(
        1L, 2L, 3L, 4L, 5:6), ptype = integer(0), class = c("vctrs_list_of", 
    "vctrs_vctr", "list"))), class = c("tbl_df", "tbl", "data.frame"
), row.names = c(NA, -5L), .drop = TRUE))
解决方案

之前代码失效的核心原因是which()默认对整列做运算,没有按行匹配对应的值和strata向量,导致索引计算错误。

写法1:rowwise行式运算(逻辑直观易读)

直接按行计算两个值在strata中的位置差,差的绝对值为1即为相邻:

bonus_dat %>%
  rowwise() %>%
  filter(
    lower %in% strata[[1]],
    upper %in% strata[[1]],
    abs(which(strata[[1]] == lower) - which(strata[[1]] == upper)) == 1
  ) %>%
  ungroup()

该写法和基础场景的判断逻辑完全对齐:

  • 基础测试中num1=1、num2=2在向量中索引差为1,返回TRUE
  • 基础测试中num1=1、num3=3在向量中索引差为2,返回FALSE

写法2:mapply向量化运算(性能更优)

如果数据量较大,可直接用mapply做行级映射,避免rowwise的性能损耗:

bonus_dat %>%
  filter(
    mapply(\(l, u, s) {
      l %in% s & u %in% s & abs(which(s == l) - which(s == u)) == 1
    }, lower, upper, strata)
  )

两种写法运行后都会过滤掉测试集中lower=500、upper=1e6这对不相邻的行,返回其余5条符合相邻要求的记录。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 00:27:19