如何在R data.table中使用group_by()和case_when()函数?

问题描述 投票:0回答:1

我是

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))
  ))
r data.table
1个回答
0
投票

使用

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))
© www.soinside.com 2019 - 2024. All rights reserved.