使用dplyr以滞后值迭代替换值

时间:2017-02-09 12:52:46

标签: r dplyr

我有以下数据框 -

 x <- c(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1)
 y <- c(0,0,0,1,0,-1,0,-1,0,1,0,-1,0,1,0,0,0)
 data <- data.frame(x,y)

我想创建一种动量指标。实际上,如果y不为零,则x取y的值,如果y为0,则x取出滞后x值的值。基本上,我是逐行替换x的值。在for循环中执行此操作很简单 -

 for (i in 1:nrow(data)) {
   data$x[i] <-
     ifelse(data$y[i] == 1, 1, ifelse(data$y[i] == -1, -1, data$x[i-1]))}

给我这个输出(我正在寻找的)

    x  y
1  NA  0
2  NA  0
3  NA  0
4   1  1
5   1  0
6  -1 -1
7  -1  0
8  -1 -1
9  -1  0
10  1  1
11  1  0
12 -1 -1
13 -1  0
14  1  1
15  1  0
16  1  0
17  1  0

然而,在非常大的数据集上,这个for循环效率非常低。我想在dplyr中实现这一点,但是我设法提出的最佳解决方案并没有做到这一点

 data2 <- data.frame(x,y)

 data2 <- 
   data2 %>% 
   mutate(x = ifelse(y == 1, 1, ifelse(y == -1, 0, Lag(x))))

返回此

    x  y
1  NA  0
2   1  0
3   1  0
4   1  1
5   1  0
6   0 -1
7   1  0
8   0 -1
9   1  0
10  1  1
11  1  0
12  0 -1
13  1  0
14  1  1
15  1  0
16  1  0
17  1  0

我的猜测是我正在尝试在dplyr中执行此操作的方式无法控制我想要做的迭代性质,即在向下移动行时替换x。有没有人有关于如何通过dplyr做到这一点的想法?

2 个答案:

答案 0 :(得分:1)

一种选择是将0替换为NA,然后进行前向填充:

library(dplyr); library(tidyr)
data %>% mutate(x = na_if(y, 0)) %>% fill(x)

#    x  y
#1  NA  0
#2  NA  0
#3  NA  0
#4   1  1
#5   1  0
#6  -1 -1
#7  -1  0
#8  -1 -1
#9  -1  0
#10  1  1
#11  1  0
#12 -1 -1
#13 -1  0
#14  1  1
#15  1  0
#16  1  0
#17  1  0

答案 1 :(得分:0)

以下是使用na.locf

中的zoo的另一个选项
library(zoo)
data$x <- with(data, na.locf(y*(NA^!y), na.rm=FALSE))