我有一个数据框,其变量RATE每隔几行就有一个NA值:
ID RATE mean_RATE sd_RATE
1 10
1 15
1 8
1 6
1 NA 9.75 3.86221
1 10
1 20
1 NA 15 7.071068
1 14
1 2
2 8
2 6
2 NA 7 1.414214
在这些行上,我想添加一个变量mean_RATE和sd_RATE,对应NA行之间所有行的平均值和sd。此平均值和sd仅在具有相同ID的所有RATE上计算:
{{1}}
正如您在上面所需的输出中所看到的,在任何均值或sd计算中都不会考虑与RATE为14和2对应的行,因为下一个NA行具有不同的ID。
有人可以通过有效的方式帮助我吗?
答案 0 :(得分:3)
我们可以使用tidyverse
library(dplyr)
df %>%
group_by(ID, grp = cumsum(lag(is.na(RATE), default = FALSE))) %>%
mutate(mean_RATE = mean(RATE, na.rm = TRUE), sd_RATE = sd(RATE, na.rm = TRUE)) %>%
mutate_at(vars(matches("_RATE")), funs(replace(., !is.na(RATE), NA)))
# A tibble: 13 x 5
# Groups: ID, grp [4]
# ID RATE grp mean_RATE sd_RATE
# <int> <int> <int> <dbl> <dbl>
# 1 1 10 0 NA NA
# 2 1 15 0 NA NA
# 3 1 8 0 NA NA
# 4 1 6 0 NA NA
# 5 1 NA 0 9.75 3.86
# 6 1 10 1 NA NA
# 7 1 20 1 NA NA
# 8 1 NA 1 15.0 7.07
# 9 1 14 2 NA NA
#10 1 2 2 NA NA
#11 2 8 2 NA NA
#12 2 6 2 NA NA
#13 2 NA 2 7.00 1.41
答案 1 :(得分:2)
您可以尝试使用ave
功能。
mutate(dat,new=ave(RATE,a<-cumsum(c(F,head(is.na(RATE),-1))),ID,
FUN = function(x)mean(x,na.rm=T)),
new=`is.na<-`(new,!is.na(RATE)),
sd=ave(RATE,a,ID,FUN=function(x)sd(x,na.rm=T)),
sd=`is.na<-`(sd,!is.na(RATE)))
ID RATE new sd
1 1 10 NA NA
2 1 15 NA NA
3 1 8 NA NA
4 1 6 NA NA
5 1 NA 9.75 5.629958
6 1 10 NA NA
7 1 20 NA NA
8 1 NA 15.00 5.629958
9 1 14 NA NA
10 1 2 NA NA
11 2 8 NA NA
12 2 6 NA NA
13 2 NA 7.00 1.414214