给出下面的数据框(按时间排序的简单时间序列):
time groups value value1
1 1 b -0.6264538 0.7383247
2 2 b 0.1836433 0.5757814
3 3 b -0.8356286 -0.3053884
4 1 a 1.5952808 1.5117812
5 2 a 0.3295078 0.3898432
6 3 a -0.8204684 -0.6212406
7 4 a 0.4874291 -2.2146999
对于每个组(a或b)以及该组中的每一行(在时间t),我想将每一行更新为当前行(在时间t)和前一行的缩放版本之和(在时间t-1)(如果前一行不存在,则不更新)
棘手的部分是,一旦一行得到更新,更新版本(而不是原始版本)应该用于更新下一行。我可以通过循环时间和组来实现这一点。我想知道是否有更有效的方法来使用lag()/ dplyr /...?
set.seed(1)
data <- data.frame(time = c(1:3, 1:4),
groups = c(rep(c("b", "a"), c(3, 4))),
value = rnorm(7), value1=rnorm(7))
alfa = 0.1
for (id in unique(data$groups)){
data_tmp <- data[data$groups==id,]
for (i in 2:nrow(data_tmp)){
for (col in colnames(data)[-(1:2)]){
data[data$groups==id,][i,][col] = data[data$groups==id,][i,][col] + alfa* data[data$groups==id,][i-1,][col]
}
}
}
期望的输出:
time groups value value1
1 1 b -0.6264538 0.7383247
2 2 b 0.1209979 0.6496138
3 3 b -0.8235288 -0.2404270
4 1 a 1.5952808 1.5117812
5 2 a 0.4890359 0.5410214
6 3 a -0.7715648 -0.5671384
7 4 a 0.4102726 -2.2714137
答案 0 :(得分:2)
你所要求的基本上是一个指数加权的移动总和。有一些软件包提供了支持这个概念的功能,但这里有一个我用过的快速功能:
EWS <- function(x, alfa = 0.1) sum(x * (alfa ^ (length(x):1 - 1)))
EWMS <- function(x, width, FUN, ...) {
FUN <- match.fun(FUN)
lenx <- length(x)
for (i in tail(seq_along(x), n = 1-width)) {
x[i] <- do.call(FUN, c(list(x[ max(1, i-width+1):i ]), list(...)))
}
x
}
(EWS
可以简单地更改为使用mean
或其他向量函数。)
简单的概念证明。 1:3的EWS(alfa
为0.1)应为
3*(10^0) + 2*(10^1) + 1*(10^2)
3*(1) + 2*(0.1) + 1*(0.01)
### R-ified/simplified to
3:1 * 10^-(0:2)
# [1] 3.00 0.20 0.01
sum(3:1 * 10^-(0:2))
# [1] 3.21
EWS(1:3, alfa=0.1)
# [1] 3.21
假设“3”是最新数据,“2”和“1”是过去。 (这很容易改变,这只是一个起点。)
移动部分同样合理。我发现电子表格是一种直接的方式来演示应该正在发生什么:
EWMS(1:5, width=2, EWS)
# [1] 1.0000 2.1000 3.2100 4.3210 5.4321
EWMS(1:5, width=3, EWS)
# [1] 1.0000 2.1000 3.2200 4.3430 5.4665
因此将其改编为@ PLapointe的dplyr
推荐:
library(dplyr)
dat %>%
group_by(groups) %>%
mutate_each(funs(EWMS(., width=2, EWS)), -time) %>%
ungroup()
# # A tibble: 7 × 4
# time groups value value1
# <int> <chr> <dbl> <dbl>
# 1 1 b -0.6264538 0.7383247
# 2 2 b 0.1209979 0.6496139
# 3 3 b -0.8235288 -0.2404270
# 4 1 a 1.5952808 1.5117812
# 5 2 a 0.4890359 0.5410213
# 6 3 a -0.7715648 -0.5671385
# 7 4 a 0.4102726 -2.2714137
答案 1 :(得分:1)
以下是dplyr
:
df1<-read.table(text="time groups value value1
1 1 b -0.6264538 0.7383247
2 2 b 0.1836433 0.5757814
3 3 b -0.8356286 -0.3053884
4 1 a 1.5952808 1.5117812
5 2 a 0.3295078 0.3898432
6 3 a -0.8204684 -0.6212406
7 4 a 0.4874291 -2.2146999",header=TRUE, stringsAsFactors=FALSE)
alfa <- 0.1
func <-function(x){x+alfa*dplyr::lag(x,default = 0)}
library(dplyr)
df1 %>%
group_by(groups) %>%
mutate_each(funs(func(.)),-time)
time groups value value1
<int> <chr> <dbl> <dbl>
1 1 b -0.6264538 0.7383247
2 2 b 0.1209979 0.6496139
3 3 b -0.8172643 -0.2478103
4 1 a 1.5952808 1.5117812
5 2 a 0.4890359 0.5410213
6 3 a -0.7875176 -0.5822563
7 4 a 0.4053823 -2.2768240