我有以下数据框 -
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 做到这一点?
一种选择是将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
这是
使用zoo
na.locf
的另一个选项
library(zoo)
data$x <- with(data, na.locf(y*(NA^!y), na.rm=FALSE))