【问题标题】:Why doesn't `pivot_wider` work on a `data.table`为什么 `pivot_wider` 不能在 `data.table` 上工作
【发布时间】:2021-03-10 20:21:54
【问题描述】:

一个从长到宽的简单示例:

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

为什么会出现这个错误?

PS:一种解决方法是使用as.data.frame(dt) 删除数据表。

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

【问题讨论】:

  • 因为 pivot_wider 需要一个数据框对象,但 data.table 具有不同的类,因此您需要在进行数据透视之前将数据表转换为数据框,或者您需要创建您的数据透视表数据表语法中的管道直接在 data.table 上。
  • GitHub 上报告了该问题。应该很容易解决。

标签: r data.table pivot-table tidyverse tidyr


【解决方案1】:

tidyr mentions only "data frame" without specifying other classes 中手动输入此函数,例如 tibble 或 data.table。所以解决你的问题,功能 要么不是为处理 data.table 而设计的,要么是pivot_wider 中存在错误。

作为一种解决方法,您现在可以使用as.data.frame(正如您已经提到的),如果您的数据很大,那么可能setDF 以避免额外的内存复制。

您也可以使用data.table 函数dcast 执行相同类型的转换。

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

【讨论】:

  • 我认为这是一些特殊情况。 pivot_widerdata.table 一起使用。 df &lt;- mtcars; setDT(df); tidyr::pivot_wider(df, names_from = cyl, values_from = mpg) 返回与 tidyr::pivot_wider(mtcars, names_from = cyl, values_from = mpg) 相同的输出
  • 这是GitHub issue。本质上,tidyr 调用 dt[col_names]。关于@RonakShah 的有趣发现,我认为从this line 开始就是原因。一些枢轴对所有变量进行了枢轴化,而另一些则没有。根据方法的不同,有两种不同的行数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-14
  • 1970-01-01
  • 1970-01-01
  • 2013-05-06
  • 1970-01-01
  • 2017-05-02
相关资源
最近更新 更多