【问题标题】:R cummax function with NA具有 NA 的 R cummax 函数
【发布时间】:2019-10-28 15:26:57
【问题描述】:

数据

data=data.frame("person"=c(1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2),
                 "score"=c(1,2,1,2,3,1,3,NA,4,2,1,NA,2,NA,3,1,2,4),
                  "want"=c(1,2,1,2,3,3,3,3,4,2,1,1,2,2,3,3,3,4))

尝试

library(dplyr)

data = data %>%
  group_by(person) %>%
  mutate(wantTEST = ifelse(score >= 3 | (row_number() >= which.max(score == 3)), 
                        cummax(score), score), 
         wantTEST = replace(wantTEST, duplicated(wantTEST == 4) & wantTEST == 4, NA))

我基本上正在努力使用 cummax 功能,但仅在特定情况下。我想保留任何值 (1-2-1-1) 除非有 3 或 4 (1-2-1-3-2-1-4) 应该是 (1-2-1-3-3 -4)。如果有 NA 值,我想结转以前的值。谢谢。

【问题讨论】:

    标签: r function dplyr max


    【解决方案1】:

    这是tidyverse 的一种方式。您可能想在group_by() 之后使用fill(),但这有点不清楚。

    data %>% 
      fill(score) %>% 
      group_by(person) %>% 
      mutate(
        w = ifelse(cummax(score) > 2, cummax(score), score)
      ) %>%
      ungroup()
    
    # A tibble: 18 x 4
       person score  want     w
        <dbl> <dbl> <dbl> <dbl>
     1      1     1     1     1
     2      1     2     2     2
     3      1     1     1     1
     4      1     2     2     2
     5      1     3     3     3
     6      1     1     3     3
     7      1     3     3     3
     8      1     3     3     3
     9      1     4     4     4
    10      2     2     2     2
    11      2     1     1     1
    12      2     1     1     1
    13      2     2     2     2
    14      2     2     2     2
    15      2     3     3     3
    16      2     1     3     3
    17      2     2     3     3
    18      2     4     4     4
    

    【讨论】:

      【解决方案2】:

      执行此操作的一种方法是首先填写 NA 值,然后为每一行检查是否任何时候在组中通过了 3 或更多的分数。如果在该点之前达到 3 的分数,我们将使用 max 分数直到该点,否则返回相同的分数。

      library(tidyverse)
      
      data %>%
        fill(score) %>%
         group_by(person) %>%
         mutate(want1 = map_dbl(seq_len(n()), ~if(. >= which.max(score == 3))
                                          max(score[seq_len(.)]) else score[.]))
      
      #   person score  want want1
      #    <dbl> <dbl> <dbl> <dbl>
      # 1      1     1     1     1
      # 2      1     2     2     2
      # 3      1     1     1     1
      # 4      1     2     2     2
      # 5      1     3     3     3
      # 6      1     1     3     3
      # 7      1     3     3     3
      # 8      1     3     3     3
      # 9      1     4     4     4
      #10      2     2     2     2
      #11      2     1     1     1
      #12      2     1     1     1
      #13      2     2     2     2
      #14      2     2     2     2
      #15      2     3     3     3
      #16      2     1     3     3
      #17      2     2     3     3
      #18      2     4     4     4
      

      【讨论】:

        【解决方案3】:

        另一种方法是使用来自purrraccumulate。我使用来自hablarif_else_ 来保证类型稳定性:

        library(tidyverse)
        library(hablar)
        
        data %>% 
          fill(score) %>% 
          group_by(person) %>% 
          mutate(wt = accumulate(score, ~if_else_(.x > 2, max(.x, .y), .y)))
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-05-03
          • 1970-01-01
          • 2021-11-26
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多