【问题标题】:data.table alternative for dplyr mutate?dplyr mutate 的 data.table 替代品?
【发布时间】:2015-04-11 22:10:38
【问题描述】:

我正在学习 R,但我不确定在 dplyr 或 data.table 上进行标准化是否有意义。 Dplyr 的语法非常好,但据我了解,它会在每个操作上复制数据帧,这是(或可能是)一个缺点。

我想不通的一件事是 mutate 的替代方法。

如果我有

df %>% group_by(foo) %>% mutate(
    bar  = cumsum(baz),
    q    = bar * 3.14)

我可以做某事

df[,c("bar"):=list(cumsum(baz)),by=foo]
df$q <- df$bar*3.14

在 data.table 中有更好的方法吗?

【问题讨论】:

  • 请重现示例...?
  • 对于初学者,第一行不需要clist。您的第二行有点突然退回到基本 R 语法。你怎么突然又用&lt;-$了?为什么不喜欢在你的第一行做类似df[,q:=bar*3.14] 的事情?
  • 使用一种或另一种语法(个人喜好除外)有区别吗?我的意思是,在第一行中,由于“...,by=foo]”,我需要该语法。
  • 您提到自己不想复制数据。所以&lt;-$ 进行复制。如果您在数据表范围内使用:=,您将避免复制。这就是:= 的全部意义所在 - 它通过引用进行更新。

标签: r data.table


【解决方案1】:

你可以这样做:

# some test data:
df <- data.table(baz = 1:10, foo = c(rep(1, 5), rep(2, 5)))

df[, bar := cumsum(baz), by = foo]
df[, q := bar*3.14]

虽然只有两行,但可读性强且易于编写。

【讨论】:

    【解决方案2】:

    使用data.table 执行此操作的惯用方式是:

    dt[, c("bar", "q") := {
           tmp = cumsum(baz)
           list(tmp, tmp*3.14)
         }, by = foo]
    

    data.table 同时计算 j 表达式,而不是单独计算(故意),因此除非将更新的值存储在变量中,否则不能引用它。

    这在许多情况下避免了意外。一个有用的场景是:

    dt[, c("a", "b") := list(pmin(a,b), pmax(a,b))]
    

    := 的行为与 base 相同,只是它通过引用更新输入对象。它不等同于mutate

    【讨论】:

    • 感谢您提供额外的 pminpmax 示例,这确实有助于说明这个概念。
    • @Arun 我不明白这里的 'dt[, c("a", "b") := list(pmin(a,b), pmax(a,b))]' 示例.它应该说明什么?
    • @deb,j 被完全评估。如果a 首先被评估为pmin(a, b),那么b 将始终为b,因为pmax(a, b) 将与a 的新值进行比较。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-30
    • 1970-01-01
    • 2019-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多