6

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
LucasMation
  • 2,408
  • 2
  • 22
  • 45
  • Because pivot_wider requires a data frame object, but a data.table has a different class, hence you need to either convert your data table to a data frame before pivoting or you'd need to create your piviting pipe in data table synstax directly on the data.table. – deschen Nov 28 '20 at 09:37
  • 1
    Check point 21 here: https://www.machinelearningplus.com/data-manipulation/datatable-in-r-complete-guide/ – deschen Nov 28 '20 at 09:38
  • 1
    Reported the issue on [GitHub](https://github.com/tidyverse/tidyr/issues/1066). Should be an easy fix. – Cole Nov 28 '20 at 13:20

1 Answers1

6

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
jangorecki
  • 16,384
  • 4
  • 79
  • 160
  • 2
    I think this is some specific case. `pivot_wider` works with `data.table`. `df <- mtcars; setDT(df); tidyr::pivot_wider(df, names_from = cyl, values_from = mpg)` returns the same output as `tidyr::pivot_wider(mtcars, names_from = cyl, values_from = mpg)` – Ronak Shah Nov 28 '20 at 09:40
  • Here's the [GitHub issue](https://github.com/tidyverse/tidyr/issues/1066). In essence, [tag:tidyr] calls `dt[col_names]`. Regarding @RonakShah's interesting find, I think starting at [this line](https://github.com/tidyverse/tidyr/blob/501a757bf983a3eb6e82f53173672a92d828236f/R/pivot-wide.R#L224) is why. Some pivots have all vars pivoted whereas others do not. There are two different row counts depending on the method. – Cole Nov 28 '20 at 13:29