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

如何检查R语言DataFrame中日期序列连贯性及忽略NA值

问题背景

现有如下示例DataFrame(实际数据包含更多日期):

library(lubridate)

df = data.frame(id = 1:5,
                date1 = dmy(c('01/02/2021','03/05/2022','01/03/2021','08/12/2021','01/02/2021')),
                date2 = dmy(c('03/02/2021','04/06/2022','03/08/2021','08/11/2022','02/05/2021')),
                date3 = dmy(c('04/03/2021','03/08/2022','06/09/2021','09/08/2022','03/06/2021')),
                date4 = dmy(c('05/08/2021','08/09/2022','09/10/2021','21/12/2022','03/07/2021')),
                date5 = dmy(c('09/11/2021','11/08/2022','04/11/2021','10/02/2023','04/11/2021')))

需求:检查每个id对应的所有日期是否连贯,即任意两个日期均满足前者小于后者(如date1<date2、date1<date3、date2<date3等所有组合)。

更新场景:存在NA值的情况

当DataFrame包含NA值时:

df = data.frame(id = 1:5,
                date1 = dmy(c('01/02/2021','03/05/2022','01/03/2021','08/12/2021','01/02/2021')),
                date2 = dmy(c('03/02/2021','04/06/2022','03/08/2021','08/11/2022','02/05/2021')),
                date3 = dmy(c('04/03/2021','03/08/2022',NA,'09/08/2022','03/06/2021')),
                date4 = dmy(c('05/08/2021','08/09/2022',NA,'21/12/2022','03/07/2021')),
                date5 = dmy(c('09/11/2021','11/08/2022','04/11/2021','10/02/2023','04/11/2021')))

应用原有方法后输出如下,其中id=3的is_coherent为NA,但实际我们希望忽略NA后判断剩余日期是否连贯:

# A tibble: 5 x 7
# Rowwise: 
     id date1      date2      date3      date4      date5      is_coherent
  <int> <date>     <date>     <date>     <date>     <date>     <lgl>      
1     1 2021-02-01 2021-02-03 2021-03-04 2021-08-05 2021-11-09 TRUE       
2     2 2022-05-03 2022-06-04 2022-08-03 2022-09-08 2022-08-11 FALSE      
3     3 2021-03-01 2021-08-03 NA         NA         2021-11-04 NA         
4     4 2021-12-08 2022-11-08 2022-08-09 2022-12-21 2023-02-10 FALSE      
5     5 2021-02-01 2021-05-02 2021-06-03 2021-07-03 2021-11-04 TRUE   

核心问题:如何让R忽略NA值,仅基于非NA日期判断连贯性?


解决方案

核心逻辑:对每行的非NA日期,检查它们是否严格按顺序递增(若非NA日期严格递增,则任意两个日期都满足前者小于后者)。

方法1:使用dplyr + purrr实现

library(dplyr)
library(purrr)
library(lubridate)

df_result <- df %>%
  rowwise() %>%
  mutate(
    # 提取当前行所有日期列的非NA值,保留原顺序
    non_na_dates = list(c_across(starts_with("date"))[!is.na(c_across(starts_with("date")))]),
    # 判断连贯性:0/1个非NA日期默认连贯;多个时检查是否和排序后一致且无重复
    is_coherent = case_when(
      length(non_na_dates) <= 1 ~ TRUE,
      TRUE ~ all(non_na_dates == sort(non_na_dates)) & !any(duplicated(non_na_dates))
    )
  ) %>%
  ungroup() %>%
  select(-non_na_dates)  # 可选:移除中间辅助列

# 查看结果
print(df_result)

方法2:基础R实现(无需额外包)

# 定义判断函数
check_coherent <- function(row) {
  # 提取当前行的所有日期列
  dates <- row[grepl("date", names(row))]
  # 筛选非NA值
  non_na_dates <- dates[!is.na(dates)]
  # 逻辑判断
  if (length(non_na_dates) <= 1) {
    return(TRUE)
  } else {
    return(all(non_na_dates == sort(non_na_dates)) & !any(duplicated(non_na_dates)))
  }
}

# 应用到DataFrame的每一行
df$is_coherent <- apply(df, 1, check_coherent)

# 查看结果
print(df)

结果说明

运行上述代码后,id=3的is_coherent会返回TRUE(剩余的date1、date2、date5严格递增),其他id的结果保持准确:

  • id=2:date5早于date4,返回FALSE
  • id=4:date3早于date2,返回FALSE
  • id=1、5:所有非NA日期严格递增,返回TRUE

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 11:53:14