Why doesn't `pivot_wider` work on a `data.table`

A simple example of long to wide pivot:

library(tidyverse)
library(data.table)

df <- data.frame(names=letters[1:3],values=1:3)
df %>% pivot_wider(names_from=names,values_from=values)
#works

dt <- data.table(names=letters[1:3],values=1:3)
dt %>% pivot_wider(names_from=names,values_from=values)
Error in data.frame(row = row_id, col = col_id) : 
  arguments imply differing number of rows: 0, 3

Why does this error happen?

PS: one fix is to remove the data tableness with as.data.frame(dt).

dt %>% as.data.frame %>% pivot_wider(names_from=names,values_from=values)
#works

1 answer

  • answered 2020-11-28 09:37 jangorecki

    Manual entry of this function in tidyr mentions only "data frame" without specifying other classes like tibble or data.table. So addressing your question, function is either not designed to handle data.table, or there is a bug in pivot_wider.

    As a workaround you can now use as.data.frame (as you already mentioned), if your data is big then possibly setDF to avoid extra in-memory copy.

    You can also use data.table function dcast to perform same kind of transformation.

    library(tidyr)
    library(data.table)
    
    df <- data.frame(names=letters[1:3],values=1:3)
    pivot_wider(df, names_from=names,values_from=values)
    ## A tibble: 1 x 3
    #      a     b     c
    #  <int> <int> <int>
    #1     1     2     3
    setDT(df)
    dcast(df, .~names, value.var="values")[, ".":=NULL][]
    #   a b c
    #1: 1 2 3