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

如何比较多日期列中指定日期对并提取对应索引?

问题需求

我有一个包含日期列的数据框,其中date_ind列表示date_col列的列索引。需要按每行date_ind指定的日期列对进行比较,找出其中较早的日期,并获取该日期对应的date_ind值。若日期相同,则选择较小的索引。目前已能获取较早日期,但不知如何提取对应的date_ind值,寻求解决方法。

示例说明

  • 第1行date_ind1=1、date_ind3=4,需比较date_col1和date_col4,date_col4更早,对应earlier_date_ind为4;
  • 第2行date_ind1=1、date_ind2=2,比较date_col1和date_col2,date_col2更早,对应索引为2。

数据

set.seed(123)
df <- data.frame(
  date_ind1 = c(1, 1, 3, 1, 1, 3, 2, 1),
  date_ind2 = c(NA, 2, NA, NA, 2, NA, 3, 4),
  date_ind3 = c(4, NA, 1, 2, NA, 1, NA, NA),
  date_col1 = sample(seq(as.Date("2000-01-01"), as.Date("2000-1-31"), by="day"), 8),
  date_col2 = sample(seq(as.Date("2000-01-01"), as.Date("2000-1-31"), by="day"), 8),
  date_col3 = sample(seq(as.Date("2000-01-01"), as.Date("2000-1-31"), by="day"), 8),
  date_col4 = sample(seq(as.Date("2000-01-01"), as.Date("2000-1-31"), by="day"), 8)
)

> df
  date_ind1 date_ind2 date_ind3  date_col1  date_col2  date_col3  date_col4
1         1        NA         4 2000-01-31 2000-01-11 2000-01-27 2000-01-10
2         1         2        NA 2000-01-15 2000-01-05 2000-01-25 2000-01-09
3         3        NA         1 2000-01-19 2000-01-20 2000-01-28 2000-01-19
4         1        NA         2 2000-01-14 2000-01-14 2000-01-30 2000-01-04
5         1         2        NA 2000-01-03 2000-01-22 2000-01-09 2000-01-14
6         3        NA         1 2000-01-10 2000-01-25 2000-01-03 2000-01-17
7         2         3        NA 2000-01-18 2000-01-30 2000-01-08 2000-01-11
8         1         4        NA 2000-01-22 2000-01-19 2000-01-07 2000-01-07

已尝试代码

library(dplyr)
col_names1 <- paste0("date_col", df$date_ind1)
col_names2 <- paste0("date_col", coalesce(df$date_ind2, df$date_ind3))
df$earlier_date <- 
  sapply(1:nrow(df), 
         function(i) min(df[ i, col_names1[i] ], df[ i, col_names2[i] ]) ) |> 
  as.Date()

期望结果

date_ind1 date_ind2 date_ind3  date_col1  date_col2  date_col3
1         1        NA         4 2000-01-31 2000-01-11 2000-01-27
2         1         2        NA 2000-01-15 2000-01-05 2000-01-25
3         3        NA         1 2000-01-19 2000-01-20 2000-01-28
4         1        NA         2 2000-01-14 2000-01-14 2000-01-30
5         1         2        NA 2000-01-03 2000-01-22 2000-01-09
6         3        NA         1 2000-01-10 2000-01-25 2000-01-03
7         2         3        NA 2000-01-18 2000-01-30 2000-01-08
8         1         4        NA 2000-01-22 2000-01-19 2000-01-07
   date_col4 earlier_date earlier_date_ind
1 2000-01-10   2000-01-10                4
2 2000-01-09   2000-01-05                2
3 2000-01-19   2000-01-19                1
4 2000-01-04   2000-01-14                1
5 2000-01-14   2000-01-03                1
6 2000-01-17   2000-01-03                3
7 2000-01-11   2000-01-08                3
8 2000-01-07   2000-01-07                4

解决方案

可以在逐行处理时,同时比较日期和对应的索引,一次性返回结果。以下提供两种实现方式:

方式1:使用dplyr的rowwise逐行处理

library(dplyr)

df_result <- df %>%
  rowwise() %>%
  mutate(
    # 获取当前行需要比较的两个date_ind值
    ind1 = date_ind1,
    ind2 = coalesce(date_ind2, date_ind3),
    # 获取对应的日期值
    date1 = get(paste0("date_col", ind1)),
    date2 = get(paste0("date_col", ind2)),
    # 确定更早的日期和对应的索引
    earlier_date = min(date1, date2),
    earlier_date_ind = case_when(
      date1 < date2 ~ ind1,
      date2 < date1 ~ ind2,
      TRUE ~ min(ind1, ind2)  # 日期相同时选较小的索引
    )
  ) %>%
  ungroup() %>%
  select(-ind1, -ind2, -date1, -date2)  # 移除中间辅助列

# 查看结果
print(df_result)

方式2:沿用原sapply思路扩展

library(dplyr)

result_list <- sapply(1:nrow(df), function(i) {
  ind1 <- df$date_ind1[i]
  ind2 <- coalesce(df$date_ind2[i], df$date_ind3[i])
  date1 <- df[i, paste0("date_col", ind1)]
  date2 <- df[i, paste0("date_col", ind2)]
  
  if (date1 < date2) {
    list(earlier_date = date1, earlier_date_ind = ind1)
  } else if (date2 < date1) {
    list(earlier_date = date2, earlier_date_ind = ind2)
  } else {
    list(earlier_date = date1, earlier_date_ind = min(ind1, ind2))
  }
})

# 将列表转成数据框并合并到原数据
df$earlier_date <- as.Date(sapply(result_list, function(x) x$earlier_date))
df$earlier_date_ind <- sapply(result_list, function(x) x$earlier_date_ind)

print(df)

两种方式都能生成符合要求的结果,满足日期相同时选择较小索引的规则。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 19:49:49