在 data.table 中的两列上滚动应用 EMA 函数
Roll-applying EMA function over two columns in data.table
我有data.table如下
dt <- structure(list(x = c(-0.888888888888886, -0.588235294117648,
0.630952380952381, 0.0769230769230788, 0.250000000000003, -0.615384615384616,
0.888888888888891, 0.924528301886792, -0.477326968973745, 0),
ema = c(-0.121833534531943, -0.148485063651126, -0.103945781102354,
-0.0936104177866151, -0.0739755367702369, -0.104913198405344,
-0.0481245077028166, NA, NA,
NA)), row.names = c(NA, -10L), class = c("data.table",
"data.frame"))
看起来像
x ema
1: -0.88888889 -0.121833535
2: -0.58823529 -0.148485064
3: 0.63095238 -0.103945781
4: 0.07692308 -0.093610418
5: 0.25000000 -0.073975537
6: -0.61538462 -0.104913198
7: 0.88888889 -0.048124508
8: 0.9245283 NA
9: -0.4773270 NA
10: 0.0000000 NA
在此data.table中,第x列是每天更新的连续变量,第ema
列是第x列的EMA(指数移动平均线)。出于某种原因,在过去的 3 天里,我无法更新 x
的 EMA(在 ema
列中),现在我需要使用下面给出的函数 ema_add
来更新它 -
ema_add <- function(newx, lasty){
ratio <- 2 / (34+1)
lasty * (1 - ratio) + ratio * newx
}
如 post - 中的建议
,我正在使用以下代码查找最后三个值的 EMA,但它没有给出所需的结果。以下是我得到的结果。
dt$updated_ema = Reduce(ema_add, x = dt$x[-1], init = first(dt$ema), accumulate = T)
dt$updated_ema
[1] -0.12183353 -0.43276804 0.27637891 0.14340835 0.21446945 -0.33876659 0.47967039 0.77624233 -0.05947054 -0.01982351
预期结果是-
x ema
1: -0.88888889 -0.121833535
2: -0.58823529 -0.148485064
3: 0.63095238 -0.103945781
4: 0.07692308 -0.093610418
5: 0.25000000 -0.073975537
6: -0.61538462 -0.104913198
7: 0.88888889 -0.048124508
8: 0.92452830 0.007455653
9: -0.47732697 -0.020246211
10: 0.00000000 -0.019089285
有人可以在应用上面的 Reduce
函数时发现我做错了什么吗?
提前致谢。
我无法真正复制您的值,但包 pracma
包含一个移动平均函数,应该可以只使用:
library(pracma)
dt[,.(x
, ema
, ema_test = movavg(x, n = 3, type="e")
)]
指数函数的移动平均函数代码为:
movavg
function (x, n, type = c("s", "t", "w", "m", "e", "r"))
{
stopifnot(is.numeric(x), is.numeric(n), is.character(type))
if (length(n) != 1 || ceiling(n != floor(n)) || n <= 1)
stop("Window length 'n' must be a single integer greater 1.")
nx <- length(x)
if (n >= nx)
stop("Window length 'n' must be greater then length of time series.")
y <- numeric(nx)
if (type == "s") {
for (k in 1:(n - 1)) y[k] <- mean(x[1:k])
for (k in n:nx) y[k] <- mean(x[(k - n + 1):k])
}
else if (type == "t") {
n <- ceiling((n + 1)/2)
s <- movavg(x, n, "s")
y <- movavg(s, n, "s")
}
else if (type == "w") {
for (k in 1:(n - 1)) y[k] <- 2 * sum((k:1) * x[k:1])/(k *
(k + 1))
for (k in n:nx) y[k] <- 2 * sum((n:1) * x[k:(k - n +
1)])/(n * (n + 1))
}
else if (type == "m") {
y[1] <- x[1]
for (k in 2:nx) y[k] <- y[k - 1] + (x[k] - y[k - 1])/n
}
else if (type == "e") {
a <- 2/(n + 1)
y[1] <- x[1]
for (k in 2:nx) y[k] <- a * x[k] + (1 - a) * y[k - 1]
}
else if (type == "r") {
a <- 1/n
y[1] <- x[1]
for (k in 2:nx) y[k] <- a * x[k] + (1 - a) * y[k - 1]
}
else stop("The type must be one of 's', 't', 'w', 'm', 'e', or 'r'.")
return(y)
}
我有data.table如下
dt <- structure(list(x = c(-0.888888888888886, -0.588235294117648,
0.630952380952381, 0.0769230769230788, 0.250000000000003, -0.615384615384616,
0.888888888888891, 0.924528301886792, -0.477326968973745, 0),
ema = c(-0.121833534531943, -0.148485063651126, -0.103945781102354,
-0.0936104177866151, -0.0739755367702369, -0.104913198405344,
-0.0481245077028166, NA, NA,
NA)), row.names = c(NA, -10L), class = c("data.table",
"data.frame"))
看起来像
x ema
1: -0.88888889 -0.121833535
2: -0.58823529 -0.148485064
3: 0.63095238 -0.103945781
4: 0.07692308 -0.093610418
5: 0.25000000 -0.073975537
6: -0.61538462 -0.104913198
7: 0.88888889 -0.048124508
8: 0.9245283 NA
9: -0.4773270 NA
10: 0.0000000 NA
在此data.table中,第x列是每天更新的连续变量,第ema
列是第x列的EMA(指数移动平均线)。出于某种原因,在过去的 3 天里,我无法更新 x
的 EMA(在 ema
列中),现在我需要使用下面给出的函数 ema_add
来更新它 -
ema_add <- function(newx, lasty){
ratio <- 2 / (34+1)
lasty * (1 - ratio) + ratio * newx
}
如 post -
dt$updated_ema = Reduce(ema_add, x = dt$x[-1], init = first(dt$ema), accumulate = T)
dt$updated_ema
[1] -0.12183353 -0.43276804 0.27637891 0.14340835 0.21446945 -0.33876659 0.47967039 0.77624233 -0.05947054 -0.01982351
预期结果是-
x ema
1: -0.88888889 -0.121833535
2: -0.58823529 -0.148485064
3: 0.63095238 -0.103945781
4: 0.07692308 -0.093610418
5: 0.25000000 -0.073975537
6: -0.61538462 -0.104913198
7: 0.88888889 -0.048124508
8: 0.92452830 0.007455653
9: -0.47732697 -0.020246211
10: 0.00000000 -0.019089285
有人可以在应用上面的 Reduce
函数时发现我做错了什么吗?
提前致谢。
我无法真正复制您的值,但包 pracma
包含一个移动平均函数,应该可以只使用:
library(pracma)
dt[,.(x
, ema
, ema_test = movavg(x, n = 3, type="e")
)]
指数函数的移动平均函数代码为:
movavg
function (x, n, type = c("s", "t", "w", "m", "e", "r"))
{
stopifnot(is.numeric(x), is.numeric(n), is.character(type))
if (length(n) != 1 || ceiling(n != floor(n)) || n <= 1)
stop("Window length 'n' must be a single integer greater 1.")
nx <- length(x)
if (n >= nx)
stop("Window length 'n' must be greater then length of time series.")
y <- numeric(nx)
if (type == "s") {
for (k in 1:(n - 1)) y[k] <- mean(x[1:k])
for (k in n:nx) y[k] <- mean(x[(k - n + 1):k])
}
else if (type == "t") {
n <- ceiling((n + 1)/2)
s <- movavg(x, n, "s")
y <- movavg(s, n, "s")
}
else if (type == "w") {
for (k in 1:(n - 1)) y[k] <- 2 * sum((k:1) * x[k:1])/(k *
(k + 1))
for (k in n:nx) y[k] <- 2 * sum((n:1) * x[k:(k - n +
1)])/(n * (n + 1))
}
else if (type == "m") {
y[1] <- x[1]
for (k in 2:nx) y[k] <- y[k - 1] + (x[k] - y[k - 1])/n
}
else if (type == "e") {
a <- 2/(n + 1)
y[1] <- x[1]
for (k in 2:nx) y[k] <- a * x[k] + (1 - a) * y[k - 1]
}
else if (type == "r") {
a <- 1/n
y[1] <- x[1]
for (k in 2:nx) y[k] <- a * x[k] + (1 - a) * y[k - 1]
}
else stop("The type must be one of 's', 't', 'w', 'm', 'e', or 'r'.")
return(y)
}