【问题标题】:What is the equivalent of mutate_at (dplyr) in data.table?data.table 中 mutate_at (dplyr) 的等价物是什么?
【发布时间】:2019-12-14 15:06:06
【问题描述】:

我正在尝试将 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()

【问题讨论】:

    标签: r data.table dplyr


    【解决方案1】:

    使用data.table,我们可以在.SDcols 中指定感兴趣的列,通过.SDlapply 循环并应用感兴趣的函数。在这里,函数rollapply 被重复,只改变width 参数。因此,最好创建一个函数来避免重复整个参数。此外,在应用函数 (f1) 时,可以将输出保存在 list 中,然后使用 recursive = FALSE 保存在 unlist 中,并将 (:=) 分配给感兴趣的列

    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
    

    请注意 funstidyverse 中已弃用,可以使用 list(~ 或仅使用 ~

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

    【讨论】:

    • 此解决方案不满足将新列名称添加到原始 tibble 的请求,如 mutate_at 所做的那样。注意到有关已弃用的乐趣。
    • @JackFahey-Gilmour。为此,它只是:=(更新了答案)
    • 如何轻松地将两个函数调用应用于同一组变量,如上所述。
    • @JackFahey-Gilmour。你有没有检查我的更新。我以为是同一个重复的东西,所以我没有早点更新
    • 有没有办法避免多链?还是您必须在单独的调用中继续链接函数?
    【解决方案2】:

    还有来自Apply multiple functions to multiple columns in data.table

    f <- function(x) lapply(c(Roll.Mean.Week=7L, Roll.Mean.Two.Week=14L),
        function(n) rollapplyr(x, width=n, mean, fill=0L, na.rm=TRUE, partial=TRUE))
    DT[, unlist(lapply(.SD, f), recursive=FALSE), A, .SDcols=B:C]
    

    输出:

         A B._Roll.Mean.Week B._Roll.Mean.Two.Week C._Roll.Mean.Week C._Roll.Mean.Two.Week
      1: 1                 1                     1               101                   101
      2: 1                 2                     2               102                   102
      3: 1                 3                     3               103                   103
      4: 1                 4                     4               104                   104
      5: 1                 5                     5               105                   105
      6: 1                 6                     6               106                   106
      7: 1                 7                     7               107                   107
      8: 1                 9                     8               109                   108
      9: 1                11                     9               111                   109
     10: 1                13                    10               113                   110
     [trunc...]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-12-12
      • 2015-08-16
      • 2014-05-08
      • 2014-06-12
      • 1970-01-01
      • 2022-11-28
      • 2021-06-19
      • 2022-06-21
      相关资源
      最近更新 更多