所以我有一个包含两列的数据框:
set.seed(123)
nrows <- 100
my_data <- data.frame(side = sample(c(-1, 1), nrows, replace = TRUE),
value = 1:nrows)
一个名为值(测量时间)和一个名为side的两个值(-1和1)。
对于每一行,我需要知道自上次出现一个边不等于当前边的行以来经过了多少时间(delta值)。在慢速R代码中:
slow_function <- function(my_data){
stopifnot(!is.null(my_data$side))
stopifnot(!is.null(my_data$value))
value_past <- rep(NA, nrow(my_data))
for(i in 2:nrow(my_data)){
current_value <- -1 * my_data$side[i]
last_mirror <- rev(which(my_data$side[1:(i-1)] == current_value))[1]
value_past[i] <- my_data$value[i] - my_data$value[last_mirror]
}
return(value_past)
}
my_data$res <- slow_function(my_data)
head(my_data)
# side value res
# 1 -1 1 NA
# 2 1 2 1
# 3 -1 3 1
# 4 1 4 1
# 5 1 5 2
# 6 -1 6 1
我尝试使用dplyr或data.table魔法快速完成此操作。
答案 0 :(得分:3)
非equi更新连接有效:
library(data.table)
setDT(my_data)
my_data[, other_side := -1*side ]
my_data[, v :=
.SD[.SD, on=.(side = other_side, value < value), mult="last", i.value - x.value ]
]
# test
my_data[ res != v, .N ] # 0
也可以通过滚动连接来完成此操作。