我有以下数据框 -
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 :(得分: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))