【问题标题】:Roll max in R. From first row to current row在 R 中滚动最大值。从第一行到当前行
【发布时间】:2021-11-23 08:39:18
【问题描述】:

我想计算从第一行到当前行的最大值

df <- data.frame(id = c(1,1,1,1,2,2,2), value = c(2,5,3,2,4,5,4), result = c(NA,2,5,5,NA,4,5))

我尝试使用 dplyr 按 id 分组并使用 zoo 中的 rollmax 函数,但没有成功

【问题讨论】:

    标签: r dplyr zoo


    【解决方案1】:

    1) rollmax 以固定宽度使用,但这里我们有一个可变宽度,因此使用 rollapplyr,这似乎接近问题的方法,我们有:

    library(dplyr)
    library(zoo)
    
    df %>%
     group_by(id) %>%
     mutate(out = lag(rollapplyr(value, 1:n(), max))) %>%
     ungroup
    

    给予:

    # A tibble: 7 x 4
    # Groups:   id [2]
         id value result   out
      <dbl> <dbl>  <dbl> <dbl>
    1     1     2     NA    NA
    2     1     5      2     2
    3     1     3      5     5
    4     1     2      5     5
    5     2     4     NA    NA
    6     2     5      4     4
    7     2     4      5     5
    

    2) 也可以通过 rollapplyr 的宽度(第二个)参数来执行分组,就像消除 dplyr 一样。在这种情况下,宽度为 1、2、3、4、1、2、3,Max 与 max 类似,只是它不使用参数 x 的最后一个元素。 (宽度的替代表达式是 seq_along(id) - match(id, id) + 1)。

    library(zoo)
    
    Max <- function(x) if (length(x) == 1) NA else max(head(x, -1))
    transform(df, out = rollapplyr(value, sequence(rle(id)$lengths), Max))
    

    给予:

      id value result out
    1  1     2     NA  NA
    2  1     5      2   2
    3  1     3      5   5
    4  1     2      5   5
    5  2     4     NA  NA
    6  2     5      4   4
    7  2     4      5   5
    

    【讨论】:

      【解决方案2】:

      data.table 选项使用 shift + cummax

      > setDT(df)[, result2 := shift(cummax(value)), id][]
         id value result result2
      1:  1     2     NA      NA
      2:  1     5      2       2
      3:  1     3      5       5
      4:  1     2      5       5
      5:  2     4     NA      NA
      6:  2     5      4       4
      7:  2     4      5       5
      

      【讨论】:

        【解决方案3】:
        library(dplyr)
        df |> 
          group_by(id) |>
          mutate(result = lag(cummax(value)))
        
        # # A tibble: 7 x 3
        # # Groups:   id [2]
        #      id value result
        #   <dbl> <dbl>  <dbl>
        # 1     1     2     NA
        # 2     1     5      2
        # 3     1     3      5
        # 4     1     2      5
        # 5     2     4     NA
        # 6     2     5      4
        # 7     2     4      5
        

        【讨论】:

          【解决方案4】:

          这是一个基本的 R 解决方案。这只会让您获得累积最大值:

          df$result = ave(df$value, df$i, FUN=cummax)
          

          要获得所需滞后的累积最大值:

          df$result = ave(df$value, df$i, FUN=function(x) c(NA,cummax(x[-(length(x))])))
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-05-09
            • 2018-10-02
            • 2014-11-27
            • 1970-01-01
            相关资源
            最近更新 更多