dcast.data.table中的未记录错误

时间:2014-06-11 00:02:19

标签: r data.table reshape2 resampling

(这是之前在data-table-help mailing list发布的,但是几周没有发表评论,我做了一些尝试调试它。)

我遇到一个奇怪的错误,互联网搜索只出现在data.table的提交日志中:

# Error in dcast.data.table(test.table, as.formula(paste(class.col, "+",  : 
#   retFirst must be integer vector the same length as nrow(i)

这是在一个data.table上运行一个先前经过测试的工作dcast.data.table表达式的。我通过随机重新采样Trial替换了子集。违规部分是:

dcast.data.table(test.table, 
                 Class + Time + Trial ~ Channel,
                 value.var = "Voltage",
                 fun.aggregate=identity)

输入表中的近似重复行似乎令人窒息(即,无论是否存在表中的id列,错误都是相同的):

test.table <- structure(list(Trial = c(1169L, 1169L), Sample = c(155L, 155L
), Class = c(1L, 1L), Subject = structure(c(13L, 13L), .Label = c("s01", 
"s02", "s03", "s04", "s05", "s06", "s07", "s08", "s09", "s10", 
"s11", "s12", "s13"), class = "factor"), Channel = c(1L, 1L), 
    Voltage = structure(c(-0.992322316444497, -0.992322316444497
    ), "`scaled:center`" = -6.23438399446429e-16, "`scaled:scale`" = 1), 
    Time = c(201.149466192171, 201.149466192171), Baseline = c(0.688151312347969, 
    0.688151312347969), id = 1:2), .Names = c("Trial", "Sample", 
"Class", "Subject", "Channel", "Voltage", "Time", "Baseline", 
"id"), class = c("data.table", "data.frame"), row.names = c(NA, 
-2L), sorted = "id")    

test.table
#    Trial Sample Class Subject Channel    Voltage     Time  Baseline id
# 1:  1169    155     1     s13       1 -0.9923223 201.1495 0.6881513  1
# 2:  1169    155     1     s13       1 -0.9923223 201.1495 0.6881513  2
dcast.data.table(test.table, 
                  Class + Time + Trial ~ Channel,
                  value.var = "Voltage",
                  fun.aggregate=identity)
# Error in dcast.data.table(test.table, Class + Time + Trial ~ Channel,  : 
#   retFirst must be integer vector the same length as nrow(i)

更改dcast公式中的单个列会接近我要查找的输出:

test.table[2,Trial:=1170]
dcast.data.table(test.table, 
                  Class + Time + Trial ~ Channel,
                  value.var = "Voltage",
                  fun.aggregate=identity)
#    Class     Time Trial          1
# 1:     1 201.1495  1169 -0.9923223
# 2:     1 201.1495  1170 -0.9923223

什么困扰数据。表?我尝试更改键并弄乱公式术语的顺序只是为了看,因为我不理解错误,但那不起作用。

如果我用dcast中的常规reshape2替换函数调用,我会得到一个看似无关的错误:

# Error in vapply(indices, fun, .default) : values must be length 0, but FUN(X[[29]]) result is length 1

此时在我的代码中,我并不关心Trial值是否正确,因此我可以通过将公式替换为id来解决此问题,但我和#39 ;我对更通用或更强大的解决方案感兴趣。

1 个答案:

答案 0 :(得分:2)

更新:已在v1.9.3的commit 1253中修复。来自NEWS

  
      
  • dcast.data.table在指定fun.aggregate时提供更好的错误消息但返回长度!= 1.关闭git #693。感谢Trevor Alexander报告here on SO
  •   

我同意错误消息应该更有助于理解问题,它通常在data.table中。这只是我没有预料到的情况。

如果您可以将问题here归档为错误,我会在一段时间后修复它。


然而,你的问题对我来说似乎是微不足道的RTFM。来自?dcast.data.table

  

fun.aggregate - 数据是否应在投射前汇总?如果公式未识别每个单元格的单个观察值,则聚合默认为带有消息的长度。

     

DETAILS 部分:“... fun.aggregate将必须使用。聚合函数应该使用向量作为输入并返回单个值(或列表长度一)作为输出。“ ...

在您的示例中,您的公式的LHS会产生两个相同的行,这意味着必须使用fun.aggregate - 如果您使用一个,则默认为length(如reshape2:::dcast一样)。你已经使用了identity,它只会返回值。因此它返回Voltage的值,函数不喜欢它。

错误消息应该是:

  

错误:fun.aggregate应为每个唯一的组(来自公式的LHS)返回长度为1的向量,但为组返回length=2

或类似的东西。随意建议更好/更清晰的错误消息。


PS:我不明白近似重复的含义。

identical(test.table[1, list(Class, Time, Trial)], 
          test.table[2, list(Class, Time, Trial)])
# [1] TRUE

如果您在LHS上使用id列,那么您应该能够获得所需的结果,因为您现在可以唯一地识别行......

dcast.data.table(test.table, 
             Class + Time + Trial ~ Channel + id,
             value.var = "Voltage",
             fun.aggregate=identity)

#    Class     Time Trial        1_1        1_2
# 1:     1 201.1495  1169 -0.9923223 -0.9923223

该函数仅考虑公式LHS中给出的列,以确定是否存在唯一行,而不是实际输入数据是否具有唯一行(如果这是混乱)。


回答OP的第二条评论:

当前获得结果(没有错误)的唯一方法是你的函数返回一个列表:

dcast.data.table(test.table, 
             Class + Time + Trial ~ Channel,
             value.var = "Voltage",
             fun.aggregate=list)
#    Class     Time Trial                     1
# 1:     1 201.1495  1169 -0.9923223,-0.9923223

然后你可以检查列是否全长为1,如果是,则取消列表。