R语言 为了可读性,将data.table链分成两行代码

mpgws1up  于 2023-06-19  发布在  其他
关注(0)|答案(3)|浏览(133)

我正在处理一个Rmarkdown文档,被告知要严格限制最大列数(margin column)为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)]

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

pokxtpni

pokxtpni1#

使用maggritr链接数据表

我有一个方法,我使用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)

其他示例

编辑:它也不仅仅是语法糖,因为它允许您将上一步中的表引用为.,这意味着您可以进行自连接,
或者你也可以使用%T>%来做一些中间的日志记录(使用futility.logger等):

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

编辑:

这是很晚了,我仍然经常使用它。但我有以下警告:
magritr增加了开销
我真的很喜欢在剧本的顶层做这个。它有一个非常清晰和可读的流程,有许多巧妙的技巧你可以用它做。
但是我以前在优化时,如果它是一个被调用了很多次的函数的一部分,我就不得不删除它。
在这种情况下,最好将数据表the old fashioned way链接起来。

**编辑2:**好吧,我回到这里说它不会增加太多开销,我只是在一些测试中尝试了基准测试,但无法真正找到任何重大差异:

library(magrittr)
library(data.table)
toplevel <- data.table::CJ(group = 1:100, sim = 1:100, letter = letters)
toplevel[, data := runif(.N)]

processing_method1 <- function(dt) {
  dt %>% 
    .[, mean(data), by = .(letter)] %>%
    .[, median(V1)]
}

processing_method2 <- function(dt) {
  dt[, mean(data), by = .(letter)][, median(V1)]
}

microbenchmark::microbenchmark(
  with_pipe = toplevel[, processing_method1(.SD), by = group],
  without_pipe = toplevel[, processing_method2(.SD), by = group]
)
Unit: milliseconds
         expr      min       lq      mean   median       uq      max neval
    with_pipe 87.18837 91.91548 101.96456 100.7990 106.2750 230.5221   100
 without_pipe 86.81728 90.74838  98.43311  99.2259 104.6146 129.8175   100```

Almost no overhead here
8i9zcol2

8i9zcol22#

您必须给予每行的[]之间返回。下面是一个将 data.table 代码分成几行的例子:

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

您也可以给予每个逗号之前/之后返回。一个逗号前有回车符的例子(我的首选):

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

请参阅下面的答案,以获得一个扩展示例

t1rydlwq

t1rydlwq3#

多年来,RStudio中自动缩进导致数据表管道不对齐的方式一直令我感到沮丧。直到最近,我才意识到有一种巧妙的方法可以解决这个问题,只需将管道操作包含在括号中即可。
下面是一个简单的例子:

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]
  )

为什么会这样?因为未闭括号向R解释器发出信号,表示当前行尚未完成,因此整个管道被视为连续的代码行。

相关问题