R cummax функция с NA - PullRequest
       38

R cummax функция с NA

3 голосов
/ 14 июня 2019

данные

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 ]

3 голосов
/ 14 июня 2019

Вот один способ с 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
0 голосов
/ 14 июня 2019

Другой способ - использовать 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)))
0 голосов
/ 14 июня 2019

Один из способов сделать это - сначала заполнить 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
...