R自定义最大功能

时间:2019-06-01 04:03:53

标签: r max

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 个答案:

答案 0 :(得分:1)

您可以使用指定的规则编写自定义函数,并按如下所示将其应用于组中的每个人,

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()

答案 1 :(得分:0)

我们可以使用cummax获得高于3或更高的分数,或保持score不变。要在前4个之后获得NA,我们可以将replace 4个值duplicated设置为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

答案 2 :(得分:0)

带有data.table的选项。将'data.frame'转换为'data.table'(setDT(data)),按'person'分组,指定i以选择'score'大于或等于3的行,得到{score}的cummax并将其分配给'WANT2',将NA元素替换为'score'值(pmax),将重复的'4'值设置为{{ 1}},每个“人”

NA

或创建一个索引,其中值4是重复的

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

然后在指定setDT(data)[, ind := NA^(duplicated(cumsum(score == 4)) & shift(score) == 4), person] 来选择分数大于或等于4的行时,按人获得“分数”的累积最大值。

i

并使用data[score >=3, WANT2 := cummax(score), person] NA元素替换为'score',同时确保重复的4是pmax(使用'ind')

NA