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

R语言无需多重for循环按行间条件筛选data.frame数据

解决方案

方法1:使用dplyr实现(简洁高效,无循环)

首先构造示例数据:

df=data.frame(Abs=c("At1", "At1", "At1", "At2", "At2", "At3", "At4", "At4", "At4", "At4", "At5", "At5", "At6", "At6", "At6"),
              vid=c("id1", "id2", "id3", "id4", "id5", "id1", "id1", "id2", "id5", "id6", "id7", "id8", "id8", "id9", "id12"),
              ert=c(1,1,2,7,8,4,5,5,5,9,6,5,2,2,2),
              Tre= c(1256, 1260, 854, 147,8962, 87452, 1452, 1500, 1502, 147, 210, 258,1400,1850,1865))

筛选代码如下:

library(dplyr)

df2 <- df %>%
  # 按Abs和ert分组,满足「同一Abs分组、ert值相同」的前提条件
  group_by(Abs, ert) %>%
  # 组内判断当前行是否满足:存在至少1个其他行,vid不同且Tre绝对差<300
  filter(any(abs(Tre - cur_data()$Tre[vid != cur_data()$vid[cur_group_rows()]]) < 300)) %>%
  ungroup()

运行后得到的结果和预期完全一致:

> df2
# A tibble: 7 × 4
  Abs   vid    ert   Tre
  <chr> <chr> <dbl> <dbl>
1 At1   id1       1  1256
2 At1   id2       1  1260
3 At4   id1       5  1452
4 At4   id2       5  1500
5 At4   id5       5  1502
6 At6   id9       2  1850
7 At6   id12      2  1865

方法2:base R实现(无需额外安装包)

如果不想依赖第三方包,可以用单层循环实现,效率远高于多重for循环:

# 按Abs+ert拆分数据
split_df <- split(df, interaction(df$Abs, df$ert))
# 对每个子集筛选符合条件的行
filtered_list <- lapply(split_df, function(sub_df) {
  n <- nrow(sub_df)
  if (n < 2) return(NULL)
  keep <- logical(n)
  for (i in seq_len(n)) {
    keep[i] <- any(abs(sub_df$Tre[i] - sub_df$Tre[-i]) < 300 & sub_df$vid[i] != sub_df$vid[-i])
  }
  sub_df[keep, ]
})
# 合并结果
df2 <- do.call(rbind, filtered_list)
rownames(df2) <- NULL

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 12:06:03