将 data.table 链分成两行代码以提高可读性

Break data.table chain into two lines of code for readability

我正在处理 Rmarkdown 文档,并被告知要严格限制最大列数(边距列)为 100。在文档的代码块中,我使用了许多不同的包,其中有 data.table.

为了遵守限制,我可以拆分链(甚至是长命令),如:

p <- ggplot(foo,aes(bar,foo2))+
       geom_line()+
       stat_smooth()
bar <- sum(long_variable_name_here,
         na.rm=TRUE)
foo <- bar %>% 
         group_by(var) %>%
         summarize(var2=sum(foo2))

但我无法拆分 data.table 链,因为它会产生错误。我怎样才能实现这样的目标?

bar <- foo[,.(long_name_here=sum(foo2)),by=var]
           [order(-long_name_here)]

当然,最后一行会导致错误。谢谢!

您必须在每行的 [] 之间给出一个 return。如何将 data.table 代码分成几行的示例:

bar <- foo[, .(long_name_here = sum(foo2)), by = var
           ][order(-long_name_here)]

您还可以在每个逗号之前/之后添加一个 return。逗号前带有 return 的示例(我的偏好):

bar <- foo[, .(long_name_here = sum(foo2))
           , by = var
           ][order(-long_name_here)
             , long_name_2 := long_name_here * 10]

使用 magrittr 链接 data.tables

我有一个正在使用的方法,使用 magrittr,使用 . 对象和 [:

library(magrittr)
library(data.table)

bar <- foo %>%
        .[etcetera] %>%
        .[etcetera] %>%
        .[etcetera]

工作示例:

out <- data.table(expand.grid(x = 1:10,y = 1:10))
out %>% 
  .[,z := x*y] %>% 
  .[,w := x*z] %>% 
  .[,v := w*z]
print(out)

其他示例

编辑:它也不仅仅是语法糖,因为它允许您将上一步中的 table 引用为 .,这意味着您可以进行自连接,

或者您可以使用 %T>% 进行一些中间步骤的登录(使用 futile.logger 等):

out %>%
 .[etcetera] %>%
 .[etcetera] %T>% 
 .[loggingstep] %>%
 .[etcetera] %>%
 .[., on = SOMEVARS, allow.cartesian = TRUE]

编辑:

这是很久以前的事了,我仍然经常使用它。但我有以下警告:

magrittr adds overhead

我真的很喜欢在脚本的顶层执行此操作。它有一个非常清晰易读的流程,你可以用它来做一些巧妙的技巧。

但是如果它是被多次调用的函数的一部分,我在优化之前必须删除它。

在这种情况下,您最好链接 data.tables

多年来,RStudio mis-aligns data.table 管道中的自动缩进方式一直令我感到沮丧。我最近才意识到有一种巧妙的方法可以解决这个问题,只需将管道操作括在括号中即可。

这是一个简单的例子:

x <- data.table(a = letters, b = LETTERS[1:5], c = rnorm(26))
y <- (
  x
  [, c := round(c, 2)]
  [sample(26)]
  [, d := paste(a,b)]
  [, .(d, foo = mean(c)), by = b]
  )

为什么这行得通?因为 un-closed 括号向 R 解释器发出当前行仍未完成的信号,因此整个管道被视为连续的代码行。