2017-06-01 31 views
2

问题:如何在发生某个值之前向后填充组中的所有行。我不是想用zoona.locf填写NA或缺失值。在下面,我想在每个ID组出现1.00之前使用1.00填充A中的所有先前行,理想情况下使用dplyr按发生次数向组填充值

输入:

data<- data.frame(ID=c(1,1,1,1,2,2,2,3,3,3,4,4,4,4,4), 
       time=c(1,2,3,4,1,2,3,1,2,3,1,2,3,4,5), 
       A=c(0.10,0.25,1,0,0.25,1,0.25,0,1,0.10,1,0.10,0.10,0.10,0.05)) 
ID time A 
1 1  0.10 
1 2  0.25 
1 3  1.00 
1 4  0.00 
2 1  0.25 
2 2  1.00 
2 3  0.25 
3 1  0.00 
3 2  1.00 
3 3  0.10 
4 1  1.00 
4 2  0.10 
4 3  0.10 
4 4  0.10 
4 5  0.05 

所需的输出:

ID time A 
1 1  1.00 
1 2  1.00 
1 3  1.00 
1 4  0.00 
2 1  1.00 
2 2  1.00 
2 3  0.25 
3 1  1.00 
3 2  1.00 
3 3  0.10 
4 1  1.00 
4 2  0.10 
4 3  0.10 
4 4  0.10 
4 5  0.05 

回答

6

通过ID分组后,您可以查看1的累计总和,并在那里它仍然低于1(尚未出现) ,用1替换A值:

data %>% 
    group_by(ID) %>% 
    mutate(A = replace(A, cumsum(A == 1) < 1, 1)) 
# Source: local data frame [15 x 3] 
# Groups: ID [4] 
# 
# ID time  A 
# <dbl> <dbl> <dbl> 
# 1  1  1 1.00 
# 2  1  2 1.00 
# 3  1  3 1.00 
# 4  1  4 0.00 
# 5  2  1 1.00 
# 6  2  2 1.00 
# 7  2  3 0.25 
# 8  3  1 1.00 
# 9  3  2 1.00 
# 10  3  3 0.10 
# 11  4  1 1.00 
# 12  4  2 0.10 
# 13  4  3 0.10 
# 14  4  4 0.10 
# 15  4  5 0.05 

颇为相似,你也可以使用cummax

data %>% group_by(ID) %>% mutate(A = replace(A, !cummax(A == 1), 1)) 

而这里的一个基础R方法:

transform(data, A = ave(A, ID, FUN = function(x) replace(x, !cummax(x == 1), 1))) 
3

我们可以使用data.table。将'data.frame'转换为'data.table'(setDT(data)),得到'A'为1的行,找到行的序列,用i将'A'中的值赋值为(:=)为1

library(data.table) 
setDT(data)[data[, .I[seq_len(which(A==1))], ID]$V1, A := 1][] 
# ID time A 
# 1: 1 1 1.00 
# 2: 1 2 1.00 
# 3: 1 3 1.00 
# 4: 1 4 0.00 
# 5: 2 1 1.00 
# 6: 2 2 1.00 
# 7: 2 3 0.25 
# 8: 3 1 1.00 
# 9: 3 2 1.00 
#10: 3 3 0.10 
#11: 4 1 1.00 
#12: 4 2 0.10 
#13: 4 3 0.10 
#14: 4 4 0.10 
#15: 4 5 0.05 

或者我们可以使用avebase R

data$A[with(data, ave(A==1, ID, FUN = cumsum)<1)] <- 1 
+0

@docendodiscimus感谢的人,你是对的。我应该更加小心..我认为这将是'setDT(data)[data [,.I [cumsum(A == 1)<1],ID] $ V1,A:= 1]' – akrun