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)))
答案 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