带有NA的R cummax函数

时间:2019-06-14 02:15:21

标签: r function dplyr max

数据

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值,我想结转以前的值。谢谢。

3 个答案:

答案 0 :(得分:3)

这是使用tidyverse的一种方法。您可能要在fill()之后使用group_by(),但这还不清楚。

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

答案 1 :(得分:0)

一种方法是首先填充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

答案 2 :(得分:0)

另一种方法是使用accumulate中的purrr。我使用if_else_中的hablar来保持类型稳定:

library(tidyverse)
library(hablar)

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