data.table 中 mutate_at (dplyr) 的等价物是什么?

JFG*_*123 5 r dplyr data.table mutate

我正在尝试将 dplyr 中的一些较慢的进程移动到使用 data.table,但是似乎无法找到一种在 data.table 中使用“mutate_at”类型方法的有效方法。特别是,在命名创建的新变量并将超过 1 个函数应用于多个列时。

下面我使用 mutate_at 将 2 个不同的函数应用到 2 个具有关联命名的不同列 + 使用 group by 语句。我希望能够在 data.table 中轻松复制它。

library(tibble)
library(zoo)

Data = tibble(A = rep(c(1,2),50),
              B = 1:100,
              C = 101:200)

Data %>% 
    group_by(A) %>% 
    mutate_at(vars(B,C), funs(Roll.Mean.Week = 7 * rollapply(., width = 7, mean, align = "right", fill = 0, na.rm = T, partial = T),
                              Roll.Mean.Two.Week = 7 * rollapply(., width = 14, mean, align = "right", fill = 0, na.rm = T, partial = T))) %>% 
    ungroup()
Run Code Online (Sandbox Code Playgroud)

akr*_*run 4

使用data.table,我们可以指定 中感兴趣的列.SDcols,循环遍历.SDwithlapply并应用感兴趣的函数。rollapply此处,仅更改参数即可重复该功能width。因此,最好创建一个函数来避免重复整个参数。此外,在应用函数 ( f1) 时,输出可以保留在 a 中list,稍后unlist使用recursive = FALSE并将 ( ) 分配:=给感兴趣的列

library(data.table)
library(zoo)
nm1 <- c("B", "C")
nm2 <- paste0(nm1, "_Roll.Mean.Week")
nm3 <- paste0(nm1, "_Roll.Mean.Two.Week")
f1 <- function(x, width) rollapply(x, width = width, mean,
        align = "right", fill = 0, na.rm = TRUE, partial = TRUE)
setDT(Data)[, c(nm2, nm3) := unlist(lapply(.SD, function(x)
  list(f1(x, 7), f1(x, 14))), recursive = FALSE), by = A, .SDcols = nm1]
head(Data)
#   A B   C B_Roll.Mean.Week C_Roll.Mean.Week B_Roll.Mean.Two.Week C_Roll.Mean.Two.Week
#1: 1 1 101                1                1                  101                  101
#2: 2 2 102                2                2                  102                  102
#3: 1 3 103                2                2                  102                  102
#4: 2 4 104                3                3                  103                  103
#5: 1 5 105                3                3                  103                  103
#6: 2 6 106                4                4                  104                  104
Run Code Online (Sandbox Code Playgroud)

请注意,它funs已被弃用tidyverse,可以使用list(~或只是~

Data %>% 
    group_by(A) %>% 
    mutate_at(vars(B,C), list(Roll.Mean.Week =  ~f1(., 7),
                              Roll.Mean.Two.Week = ~ f1(., 14)))%>% 
    ungroup()
Run Code Online (Sandbox Code Playgroud)