r - R基础管道进入`do.call`
问题描述
假设我有一个myList
由一些data.frame
对象组成的列表 ( ),并且我想使用方法将列表中的所有元素折叠成一个data.frame
结构:rbind
do.call
set.seed(123)
myList <- list(
a = data.frame(
h1 = rnorm(5),
h2 = rnorm(5)
),
b = data.frame(
h1 = rnorm(5),
h2 = rnorm(5)
)
)
使用magrittr
' 的管道运算符 ( %>%
),您可以执行以下操作,其中do.call
( args
) 中的第二个参数是由 a 表示的 lhs 表达式.
:
myList %>% do.call("rbind", .)
但是使用新的基础管道 ( |>
) 会导致执行相同操作时出错:
myList |> do.call("rbind", .)
#> Error in do.call(myList, "rbind", .) :
#> second argument must be a list
将这个(和其他类似操作)管道到 R 的新基础管道运算符的正确方法是什么,其中 lhs 表达式不一定是方法中的第一个参数?
解决方案
1) 命名参数 |>
总是插入到第一个参数中并且不支持 dot 但这有效:
myList |> do.call(what = "rbind")
2)匿名函数调用虽然有点冗长,但这也有效:
myList |> (\(args) do.call("rbind", args))()
2a) 命名函数或像 do.call 一样定义 Do.call 但交换了前两个参数:
Do.call <- \(args, what, ...) do.call(what, args, ...)
myList |> Do.call("rbind")
2b)或定义一个接受第二个参数、函数以及第一个和剩余参数的函数。
Swap <- \(x, fun, y, ...) fun(y, x, ...)
myList |> Swap(do.call, "rbind")
3) myList 结构已知如果您知道 myList 恰好有两个组件并且它们被命名为 a 和 b 那么这也可以工作:
myList |> with(rbind(a, b))
4) 管道替代品当然,没有什么可以阻止继续使用 magrittr 管道。也可以使用Bizarro pipe,它不是真正的管道,但看起来像一个,只需要基础 R 即可:
myList ->.;
do.call("rbind", .)
5) rbind Alternatives使用 dplyr 中的 bind_rows 或 data.table 中的 rbindlist 代替使用 rbind:
library(dplyr)
myList |> bind_rows()
library(data.table)
myList |> rbindlist()
6) do.call Alternatives 使用reduce from purrr 而不是do.call,至少在这个例子中是有效的。
library(purrr)
myList |> reduce(rbind)
推荐阅读
- java - ORA-00933: SQL 命令未正确结束 Java
- android - 如何为 xamarin android 实现推送通知
- scala - Scala defaulting typed list to be of type String
- r - 在 1024 行之后将写入数据库问题编码到 SQL
- javascript - 打印 div 在 angularjs 中不起作用
- awk - Can't while loops be used on arrays in awk?
- java - 如何以编程方式更改线性布局宽度/高度
- c - 如何用字符串初始化数组以及如何计算双字符的char值
- javascript - 如何确定 AWS.EC2.runInstances 是否成功创建了实例?
- qt - Qt,以 PDF 格式打印 QDialog,质量问题