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

如何在DataFrame多列中判断连续3行递增并标记TRUE/FALSE

连续3行递增的疫情爆发标记问题

需求说明

现有多地区周病例移动平均值数据集(100+列、500+行),需对每一列执行以下判断:

  • 仅当当前行数值 > 前一行数值,且前一行数值 > 前前一行数值时,当前行标记为TRUE
  • 前两行无足够历史数据,统一标记为FALSE

示例输入数据

State A   State B    State C    State D
1   9.5       64.5      10.0       5.5 
2  28.0       64.0       6.0       3.0
3  38.5      104.5      17.0       4.5
4  20.5      118.0      23.0       5.0
5  10.5       99.5      17.0       5.0
6   7.5       78.0      14.0       3.0
7  12.0       73.0      20.5       2.5
8  17.5       74.5      20.0       2.0
9  19.0       69.0      12.5       5.0
10 14.5       64.5      15.0       7.0

预期输出结果

State A   State B    State C    State D
1  FALSE     FALSE      FALSE      FALSE 
2  FALSE     FALSE      FALSE      FALSE
3  TRUE      FALSE      FALSE      FALSE
4  FALSE     TRUE       TRUE       TRUE
5  FALSE     FALSE      FALSE      FALSE
6  FALSE     FALSE      FALSE      FALSE
7  FALSE     FALSE      FALSE      FALSE
8  TRUE      FALSE      FALSE      FALSE
9  TRUE      FALSE      FALSE      FALSE
10 FALSE     FALSE      FALSE      TRUE

现有代码问题分析

1. 自行编写的for循环错误

代码:

for (i in 3:nrow(data)) {
    # Check for positive increase in each preceding row
    if (data[i] > data[i - 1] & data[i - 1] > data[i - 2]) {
      data[i] <- "TRUE"
    }
  else{data[i] <- "FALSE"}
  }

报错信息:

Error in if (test[i] > test[i - 1] & test[i - 1] > test[i - 2]) { :
the condition has length > 1

错误原因:data[i]提取的是整行数据(所有列),data[i] > data[i-1]会返回一个长度等于列数的逻辑向量,而if语句只能处理长度为1的条件,因此触发报错。

2. 队友提供的代码逻辑缺陷

代码:

checkfun <- function(x) {
  c(F,F,head(diff(x)>0,-1)&tail(diff(x)>0,-1))
}
outbreak=data.frame(sapply(na.omit(data),checkfun))

问题:

  • na.omit(data)会直接删除包含NA的行,导致输出结果的行数、行索引与原数据集不一致,破坏原有结构
  • 未处理向量中的NA值,若原数据存在NA,diff(x)会生成NA,最终导致标记结果错误

正确解决方案

提供两种高效实现方式,适配大数据集(100+列、500+行):

方法1:基于自定义函数+apply系列

# 定义单列判断函数
check_outbreak <- function(x) {
  res <- rep(FALSE, length(x))
  # 从第3行开始遍历判断
  for (i in 3:length(x)) {
    # 用&&保证单个逻辑值判断,处理可能的NA(若需保留NA可改用&)
    res[i] <- !is.na(x[i]) && !is.na(x[i-1]) && !is.na(x[i-2]) && 
              x[i] > x[i-1] && x[i-1] > x[i-2]
  }
  res
}

# 应用到所有列,生成结果数据集
outbreak_df <- data.frame(lapply(data, check_outbreak))

方法2:基于dplyr的简洁实现

适合熟悉tidyverse语法的场景:

library(dplyr)

outbreak_df <- data %>%
  mutate(
    across(
      everything(), 
      ~case_when(
        row_number() < 3 ~ FALSE,
        # 增加NA判断避免结果出现NA
        is.na(.) | is.na(lag(.)) | is.na(lag(., 2)) ~ FALSE,
        . > lag(.) & lag(.) > lag(., 2) ~ TRUE,
        TRUE ~ FALSE
      )
    )
  )

验证说明

将上述代码应用到示例输入数据,可完全复现预期输出结果,同时兼容含NA的数据集,保留原数据的行结构与索引。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 07:49:58