Suppose I have a list (myList) consisting of some data.frame objects and I want to collapse all of the elements within the list into one data.frame structure using rbind in a do.call method:
set.seed(123)
myList <- list(
a = data.frame(
h1 = rnorm(5),
h2 = rnorm(5)
),
b = data.frame(
h1 = rnorm(5),
h2 = rnorm(5)
)
)
Using magrittr's pipe operator (%>%), you could do something like this where the second argument in do.call (args) is the lhs expression as denoted by a .:
myList %>% do.call("rbind", .)
But using the new base pipe (|>) leads to errors performing the same operation:
myList |> do.call("rbind", .)
#> Error in do.call(myList, "rbind", .) :
#> second argument must be a list
What is the proper way of piping this (and other similar operations) into R's new base pipe operator where the lhs expression isn't necessarily the first argument in a method?
1) named argument |> always inserts into the first argument and does not support dot but this works:
myList |> do.call(what = "rbind")
2) anonymous function call Although a bit verbose this also works:
myList |> (\(args) do.call("rbind", args))()
2a) named function or define Do.call like do.call but with the first two arguments swapped:
Do.call <- \(args, what, ...) do.call(what, args, ...)
myList |> Do.call("rbind")
2b) or define a function which accepts the second argument, the function and the first and remaining arguments.
Swap <- \(x, fun, y, ...) fun(y, x, ...)
myList |> Swap(do.call, "rbind")
3) myList structure known If you knew that myList had exactly two components and they were named a and b then this would also work:
myList |> with(rbind(a, b))
4) Pipe Alternatives Of course there is nothing to prevent continued use of the magrittr pipe. Also the Bizarro pipe, which is not really a pipe but looks like one, and only requires base R can be used:
myList ->.;
do.call("rbind", .)
5) rbind Alternatives Instead of using rbind use bind_rows from dplyr or rbindlist from data.table:
library(dplyr)
myList |> bind_rows()
library(data.table)
myList |> rbindlist()
6) do.call Alternatives Use reduce from purrr instead of do.call which, at least in this example, works.
library(purrr)
myList |> reduce(rbind)
Since this was posted R added _ like this. It must be used with a named argument.
myList |> do.call("rbind", args = _)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With