R Пользовательские Макс. Функция - PullRequest
1 голос
/ 01 июня 2019
data=data.frame("person"=c(1,1,1,1,2,2,2,2,3,3,3,3,4,4,4),
                "score"=c(1,2,3,2,2,1,2,3,2,3,1,4,1,4,3),
                "WANT"=c(1,2,3,3,2,1,2,3,2,3,3,4,1,4,NA))

Для каждого человека мы отслеживаем его оценки, пока они не наберут «опытный» (3) или превосходство (4). Если человек набирает превосходство (4), то это значение сохраняется, а следующий человек снимается (см. Лицо 4; вместо NA, однако, просто хотел бы удалить этот ряд). Если человек набрал опытный (3), то это значение переносится вперед, ЕСЛИ МЕНЬШЕ не набирается 4, что заменило бы балл 3. В противном случае значения остаются такими же, как они. Я попробовал cummax func, но не уверен, как применить такое правило.

Это моя попытка ниже

data$want = ave(data$score, data$person, FUN = function(x) cummax(replace(x, is.na(x), -1)))

Ответы [ 3 ]

2 голосов
/ 01 июня 2019

Вы можете написать пользовательскую функцию с указанными вами правилами и применить ее к каждому человеку в группе следующим образом:

library(dplyr)

count_3_4 <- function(vec){
  max = 0
  for(i in seq_along(vec)){
    if(vec[i] > max){
      max = vec[i]
      if(max == 3 || max == 4){
        vec[i] = max
      }
    }else if(max == 4 && vec[i] < max){
      vec[i] = NA
    }else{
      if(max == 3 || max == 4){
        vec[i] = max
      }
    }
  }
  return(vec)
}

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

data%>%
  group_by(person)%>%
  mutate(TestVal = count_3_4(score)) %>%
  ungroup()
0 голосов
/ 01 июня 2019

Опция с data.table.Преобразуйте «data.frame» в «data.table» (setDT(data)), сгруппированный по «person», укажите i, чтобы выбрать строки, в которых «Score» больше или равен 3, получите cummax«Оценка» и присвойте его «WANT2», замените элементы NA на значение «Оценка» (pmax), установите дублированные значения «4» на NA для каждого «человека»

library(data.table)
setDT(data)[score >=3,  WANT2 := cummax(score), person
     ][, WANT2 := pmax(score, WANT2, na.rm = TRUE), person]
i1 <- data[WANT2 == 4, .I[duplicated(WANT2)], person]$V1
data[i1, WANT2 := NA]     
data
#    person score WANT WANT2
# 1:      1     1    1     1
# 2:      1     2    2     2
# 3:      1     3    3     3
# 4:      1     2    3     2
# 5:      2     2    2     2
# 6:      2     1    1     1
# 7:      2     2    2     2
# 8:      2     3    3     3
# 9:      3     2    2     2
#10:      3     3    3     3
#11:      3     1    3     1
#12:      3     4    4     4
#13:      4     1    1     1
#14:      4     4    4     4
#15:      4     3   NA    NA

Или создайте индекс, в котором дублируется значение 4

setDT(data)[, ind := NA^(duplicated(cumsum(score == 4)) & 
         shift(score) == 4), person]

, затем получите кумулятивный максимум "показателя" по человеку, указав i, чтобы выбрать строки, в которых показатель равенбольше или равно 4

data[score >=3, WANT2 := cummax(score), person]

и замените элементы NA на «Score», используя pmax, убедившись, что дублированный 4 равен NA (используя «ind»)

data[, WANT2 := pmax(score, WANT2, na.rm = TRUE) * ind]
0 голосов
/ 01 июня 2019

Мы могли бы использовать cummax для оценки выше 3 или более или оставить score как есть. Чтобы получить NA с после первых 4, мы можем replace значения duplicated 4 как NA.

library(dplyr)

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


#   person score  WANT WANT2
#    <dbl> <dbl> <dbl> <dbl>
# 1      1     1     1     1
# 2      1     2     2     2
# 3      1     3     3     3
# 4      1     2     3     3
# 5      2     2     2     2
# 6      2     1     1     1
# 7      2     2     2     2
# 8      2     3     3     3
# 9      3     2     2     2
#10      3     3     3     3
#11      3     1     3     3
#12      3     4     4     4
#13      4     1     1     1
#14      4     4     4     4
#15      4     3    NA    NA
...