Search code examples
rdata.tablemagrittr

Possible to use data.table's rbindlist in a pipe


Is it possible to use data.table rbindlist in a piped operation? I posted a MWE below. I try to create a data.table c by piping in the rbindlist but get an error.

Instead, I have to manipulate c and then assign the rbindlist to c (but c is used within the list argument in rbindlist. If possible, I would like to avoid that, which I tried to accomplish through the rbindlist in the pipe up above. Is this possible?

Any help is appreciated, thanks.

library(data.table)
library(magrittr)

a <- data.table(colA = 1:10,
                colB = 11:20)

b <- data.table(colA = 300,
                colB = 500)

c <- a %>% 
  .[, colB := colB * 10] %>% 
  rbindlist(list(.,b),
            use.names = TRUE,
            fill = TRUE)
#> Error in rbindlist(., list(., b), use.names = TRUE, fill = TRUE): idcol must be a logical or character vector of length 1. If logical TRUE the id column will named '.id'.

c <- a %>% 
  .[, colB := colB * 10]

c <- rbindlist(list(c,b),
               use.names = TRUE,
               fill = TRUE)

Solution

  • It is indeed possible, but you want to use extra braces for that:

    c <- a %>% 
      .[, colB := colB * 10] %>% 
      {rbindlist(list(.,b), use.names = TRUE, fill = TRUE)}
    

    The reason for this is pretty evident from the error itself:

    # Error in rbindlist(., list(., b), use.names = TRUE, fill = TRUE): ...
    

    That is, your attempt is equivalent to

    rbindlist(aTransformed, list(aTransformed, b), use.names = TRUE, fill = TRUE)
    

    which clearly wasn't your intention and does not work as rbindlist wants to receive a list of objects to bind as the first argument. Now if we want to use the shortcut . but don't want to pass the data to the first argument, we can use extra brackets {} to create an expression. Expressions are of type {x <- 2; y <- x^2; y + x} returning y + x, so it kind of makes sense that %>% doesn't that to pass the data as the first argument, since there is none.