在使用 data.table::dcast 创建的 data.table 上使用 pander 时出错

Error when using pander on a data.table created with data.table::dcast

这是一个更有趣的问题,因为我找到了解决方法,尽管我觉得它不太好。

当我更新 pander 包(到 0.6.1)时,每当我尝试在由 [=29= 构造的宽格式 data.table 上使用 pander() ](包版本 1.10.4-3 或更早)使用 data.table::dcast():

的长格式

Error in data.table::setattr(x, "row.names", row.names.dt) : row names must be 'character' or 'integer', not 'double'

我试图删除任何行名称,但无济于事。经过一些研究,我发现 reshape2::dcast 没有错误,但是 reshape2::dcast 将 data.table 转换为 data.frame,这不是我想要的。当然,我可以将 data.frame 转换回 data.table。

这是一些为我产生错误的示例代码:

library(pander)
library(data.table)

dt.long <- data.table(time=c(1, 1, 2, 2), T=c("c", "t", "c", "t"), count=c(10, 15, 15, 20))
pander(dt.long) # this works fine

dt.wide <- dcast(dt.long, time~T, value.var = "count")
row.names(dt.wide) <- NULL # doesn't help
row.names(dt.wide) <- c() # doesn't help either
pander(dt.wide) # produces error

# work-around
library(reshape2)
dt.wide <- dcast(dt.long, time~T, value.var = "count")
pander(dt.wide) # works fine
class(dt.wide) # but this is a data.frame
dt.wide <- data.table(dt.wide) # now it is a data.table again

有没有一种简单的方法可以将数据保持为 data.table 并像以前一样使用 pander?
我使用 R 版本 3.3.2,以防万一。

提前致谢!

造成问题的是附加属性。将 'sorted' attr 设置为 'NULL' 它应该可以工作

dt.wide <- dcast(dt.long, time~T, value.var = "count")
attr(dt.wide, "sorted") <- NULL

或使用setattr

setattr(dt.wide, 'sorted', NULL)
pander(dt.wide)
#----------------
# time   c    t  
#------ ---- ----
#  1     10   15 

#  2     15   20 
#----------------

除了在调用 pander() 时将 dt.wide 强制为 data.frame 的明显解决方法(dt.wide 保持不变)

pander(as.data.frame(dt.wide))
----------------
 time   c    t  
------ ---- ----
  1     10   15 

  2     15   20 
----------------

pander()data.table 方法有一个 keys.as.row.names 参数(参见 ?pander.data.table)。该参数默认为TRUE

因此,另一种解决方法是将此参数设置为 FALSE:

pander(dt.wide, keys.as.row.names = FALSE)
----------------
 time   c    t  
------ ---- ----
  1     10   15 

  2     15   20 
----------------

但是,我认为 pander() 中存在错误,因为 dt.wide 未键入。它只是将 sorted 属性设置为 time:

str(dt.wide)
Classes ‘data.table’ and 'data.frame':    2 obs. of  3 variables:
 $ time: num  1 2
 $ c   : num  10 15
 $ t   : num  15 20
 - attr(*, ".internal.selfref")=<externalptr> 
 - attr(*, "sorted")= chr "time"

请注意,如果 time 列定义为 整数 pander(dt.wide) 不会引发错误,但会忽略 time 列从结果。 (参见 GitHub issue)。