我是
data.table
的新手,但我知道在我的特定情况下使用它可能会更快,在这种情况下,我想使用 EMA()
包中的 TTR
计算指数加权移动平均值。
我下面有一些示例数据,它比我的真实数据集小得多。我当前的代码(有点慢)使用
dplyr
按 par
和 cat
进行分组,因为我希望根据这些变量执行这些 EMA()
函数。如果我要使用 data.table
选项,我不确定如何转换 case_when()
函数(并按两个变量分组),因为我希望 EMA()
的窗口对于每个级别/唯一的都不同cat
的值。
我可以帮忙编写以下
data.table
代码吗?谢谢。
library(tidyverse)
library(data.table)
library(TTR)
set.seed(0)
par <- rep(paste("Par", 1:5), each = 100)
cat <- rep(LETTERS[1:5], each = 100)
val <- rnorm(500, 100, 20)
df <- data.frame(par, cat, val)
new_df <- df %>%
group_by(par, cat) %>%
mutate(acute = EMA(val, n = 7, ratio = 2 / (1 + 7))) %>%
mutate(chron = case_when(
cat == "A" ~ EMA(val, n = 42, ratio = 2 / (1 + 42)),
cat == "B" ~ EMA(val, n = 28, ratio = 2 / (1 + 28)),
cat %in% c("C", "D", "E") ~ EMA(val, n = 14, ratio = 2 / (1 + 14))
))
使用
acute和chron的复合赋值
`:=`()
,后者与ifelse
或如评论中建议的fcase
,数据分组为by=
a list
。
library(data.table); library(TTR)
new_dt <- as.data.table(df)
new_dt[, `:=`(
acute = EMA(val, ratio=2 / (1 + 7)),
chron = EMA(val, ratio=2 / (1 + fcase(cat == 'A', 42, cat == 'B', 28, TRUE, 14)))
), by=list(par, cat)]
all.equal(as.data.frame(new_df), as.data.frame(new_dt), check.attributes=F)
# [1] TRUE
注意,有一个警告
"both 'n' and 'ratio' are specified; using 'n'"
,所以我删除了其中一个。
数据:
set.seed(42)
df <- data.frame(par=rep(paste("Par", 1:5), each=100),
cat=rep(LETTERS[1:5], each=100),
val=rnorm(500, 100, 20))