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

在R中为每行按日期顺序生成列名序列的新列

为每行生成按日期排序的列名序列并添加为新列

需求说明

现有一个包含多列日期的DataFrame,需要为每行生成按日期从最早到最新排序的列名序列,并将该序列作为新列seq添加到原DataFrame中。

初始数据

数据创建代码

df <- data.frame(
  ID = c(1,2,3,4,5,6),
  col1 = as.Date(c("2011-02-01","2020-09-01",NA,"2010-06-01",NA,"2015-02-02")),
  col2 = as.Date(c("2010-02-01","2018-09-01","2012-03-01",NA,NA,NA)),
  col3 = as.Date(c("1998-09-02",NA,"2013-06-01","2003-05-01","2000-02-01",NA)),
  col4 = as.Date(c("2020-04-01",NA,"2019-09-10","2014-03-05",NA,"2000-08-12"))
)

初始表格

ID       col1       col2       col3       col4
1  1 2011-02-01 2010-02-01 1998-09-02 2020-04-01
2  2 2020-09-01 2018-09-01         NA         NA
3  3         NA 2012-03-01 2013-06-01 2019-09-10
4  4 2010-06-01         NA 2003-05-01 2014-03-05
5  5         NA         NA 2000-02-01         NA
6  6 2015-02-02         NA         NA 2000-08-12

期望结果

结果数据代码

result_df <- data.frame(
  ID = c(1,2,3,4,5,6),
  col1 = as.Date(c("2011-02-01","2020-09-01",NA,"2010-06-01",NA,"2015-02-02")),
  col2 = as.Date(c("2010-02-01","2018-09-01","2012-03-01",NA,NA,NA)),
  col3 = as.Date(c("1998-09-02",NA,"2013-06-01","2003-05-01","2000-02-01",NA)),
  col4 = as.Date(c("2020-04-01",NA,"2019-09-10","2014-03-05",NA,"2000-08-12")),
  seq = c("col3_col2_col1_col4","col2_col1","col2_col3_col4","col3_col1_col4","col3","col4_col1")
)

结果表格

ID       col1       col2       col3       col4                 seq
1  1 2011-02-01 2010-02-01 1998-09-02 2020-04-01 col3_col2_col1_col4
2  2 2020-09-01 2018-09-01         NA         NA           col2_col1
3  3         NA 2012-03-01 2013-06-01 2019-09-10      col2_col3_col4
4  4 2010-06-01         NA 2003-05-01 2014-03-05      col3_col1_col4
5  5         NA         NA 2000-02-01         NA                col3
6  6 2015-02-02         NA         NA 2000-08-12           col4_col1

解决方案

方法1:基础R实现

利用apply函数逐行处理,筛选非NA日期、排序后拼接列名:

# 生成排序后的列名序列
df$seq <- apply(df[, -1], 1, function(row) {
  # 筛选非NA的日期对应列
  non_na_idx <- !is.na(row)
  if (sum(non_na_idx) == 0) return("")
  
  # 获取日期和对应列名
  target_dates <- row[non_na_idx]
  target_cols <- names(df)[-1][non_na_idx]
  
  # 按日期排序列名并拼接
  sorted_cols <- target_cols[order(target_dates)]
  paste(sorted_cols, collapse = "_")
})

方法2:tidyverse实现

结合dplyr的行处理和purrr的列表操作,代码更直观:

library(tidyverse)

df <- df %>%
  rowwise() %>%
  mutate(
    seq = list(
      # 把当前行的日期列转为长格式
      enframe(c_across(col1:col4), name = "col", value = "date") %>%
        drop_na(date) %>%  # 去除NA值
        arrange(date) %>%  # 按日期排序
        pull(col)  # 提取排序后的列名
    ) %>%
      map_chr(~paste(., collapse = "_"))  # 拼接成字符串
  ) %>%
  ungroup()

两种方法都能得到符合期望的结果,可根据个人习惯选择使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 13:15:12