【问题标题】:Fill down first row within each cumulative max, with a twist填充每个累积最大值内的第一行,有一个扭曲
【发布时间】:2021-03-04 09:53:22
【问题描述】:

我有按“日期”排序的数据,其中一些值是“x”和它们的累积最大值“cmx”。我想创建一个列'max_date',它是每个累积最大值内第一行的日期。稍加改动:当有多个“x”值等于当前累积最大值时,应为这些行中的每一行选择一个新的“最大日期”。

注释了两个不同的cummax的一些数据:

d = structure(list(date = structure(c(18690, 18691, 18692, 18693, 18694, 18695, 18696, 18697), class = "Date"),
                   x = c(18, 70, 57, 94, 94, 13, 98, 23),
                   cmx = c(18, 70, 70, 94, 94, 94, 98, 98)),
                   row.names = c(NA, -8L), class = c("data.table", "data.frame"))
d
#          date  x cmx
# 1: 2021-03-04 18  18
# 2: 2021-03-05 70  70 # first row of cummax 70: select this date for row 2 & 3 
# 3: 2021-03-06 57  70 # 
# 4: 2021-03-07 94  94 # first row of cummax 94
# 5: 2021-03-08 94  94 # x is equal to cummax 94 again! 
# 6: 2021-03-09 13  94 # I.e. row 5 is a 'new' first date to be used for row 5 & 6  
# 7: 2021-03-10 98  98
# 8: 2021-03-11 23  98

因此,期望的结果:

#          date  x cmx   max_date
# 1: 2021-03-04 18  18 2021-03-04 
# 2: 2021-03-05 70  70 2021-03-05
# 3: 2021-03-06 57  70 2021-03-05
# 4: 2021-03-07 94  94 2021-03-07
# 5: 2021-03-08 94  94 2021-03-08
# 6: 2021-03-09 13  94 2021-03-08
# 7: 2021-03-10 98  98 2021-03-10
# 8: 2021-03-11 23  98 2021-03-10 

我以为我可以使用frollapply,但无法让滚动窗口查看之前的所有行。

【问题讨论】:

  • frollapply 默认查看之前的行,不像 zoo 的 rollapply

标签: r data.table


【解决方案1】:

使用cumsum(x == cmx) 创建将连续行分隔开的组,其中“x”等于cummax(x)。在每个组中,将“max_date”设置为第一个“日期”。

d[ , max_date := date[1], by = cumsum(x == cmx)]
d
#          date  x cmx   max_date
# 1: 2021-03-04 18  18 2021-03-04
# 2: 2021-03-05 70  70 2021-03-05
# 3: 2021-03-06 57  70 2021-03-05
# 4: 2021-03-07 94  94 2021-03-07
# 5: 2021-03-08 94  94 2021-03-08
# 6: 2021-03-09 13  94 2021-03-08
# 7: 2021-03-10 98  98 2021-03-10
# 8: 2021-03-11 23  98 2021-03-10

避免使用by 的第二种选择(可能在某些情况下更快):

d[rowid(cumsum(x == cmx)) == 1, max_date := date]
d[ , max_date := nafill(max_date, type = "locf")]

使用cumsum(x == cmx) 创建将连续行分隔开的组,其中“x”等于cummax(x)(否则rowid(cmx) 就足够了)。使用rowid 在组内创建计数器。对于每个组中的第一行 (rowid == 1),将“max_date”设置为“date”。使用 nafill 和 'last-observation-carried-forward' 填充 NA 行。

【讨论】:

  • 谢谢,它运行得非常好,甚至在我拥有的 200 万行数据中,它的速度也很快。如果您想看看,我添加了另一个基于第二高最大值的问题。 stackoverflow.com/questions/66535778/…>
【解决方案2】:
  1. 将表格转换为数据框

  2. 使用匹配函数查找索引

  3. 查找与该索引对应的日期

  4. 添加包含该最大日期值的列

    df

    dfSub

    打印(最大日期)

    max_date

【讨论】:

  • 这只是给了我所有行的最大值??
  • 假设您正在寻找第一个最大值的日期,我已经更新了我的答案。
  • 我需要新列中的日期,因此对于每一行,max_date 列显示达到最大值的日期 - 它也必须是最后一个日期,而不是第一个。跨度>
  • 原帖说“如果2个或多个日期的值相同,那么只需要返回最近的日期”
  • 是的,日期是有序的,所以第一个最大值将是最旧的日期,我需要最近的日期。因此,如果在第 3 天,第 1 天和第 2 天都具有相同的最大值,则第 3 行将显示第 2 天的日期,而不是第 1 天,因为它是较新的日期
猜你喜欢
  • 2021-02-08
  • 1970-01-01
  • 1970-01-01
  • 2021-05-07
  • 2018-06-28
  • 1970-01-01
  • 2016-08-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多