【问题标题】:Why does dcast not accept x[length(x)]?为什么 dcast 不接受 x[length(x)]?
【发布时间】:2020-01-18 13:15:35
【问题描述】:

我一直在努力通过获取最后一个元素来聚合 dcast。这是一个例子:

x <- data.table::data.table(foo = "bar", value = c(1, 0))
x

#    foo value
# 1: bar     1
# 2: bar     0
data.table::dcast(x, ... ~ foo, fun.aggregate = function(x) x[length(x)])

# Error: Aggregating function(s) should take vector inputs and return a single value (length=1).
# However, function(s) returns length!=1. This value will have to be used to fill any missing
# combinations, and therefore must be length=1. Either override by setting the 'fill' argument
# explicitly or modify your function to handle this case appropriately.

dcastreshape2 版本也会发生这种情况,如果使用 data.frame 而不是 data.table

我可以通过多种方式让它发挥作用。例如,我可以使用

data.table::dcast(x, ... ~ foo, fun.aggregate = function(x) rev(x)[1L])

#    . bar
# 1: .   0

并得到预期的结果。 dplyr::last() 函数也有效,data.table::last() 无效。

但是,我感兴趣的是为什么使用 x[length(x)] 不起作用。如果我将中间打印命令放在聚合函数中以弄清楚发生了什么,我会得到以下信息:

data.table::dcast(x, ... ~ foo,
                  fun.aggregate = function(x) {print(x); print(length(x)); 5L}, value.var = "value")

# numeric(0)
# [1] 0
# [1] 1 0
# [1] 2
#    . bar
# 1: .   5

这表明dcast 正在迭代一个不在表中的foo 值,并且不能存在于其他地方,因为foo 是一个简单的字符向量,而不是因子向量。发生了什么事?

R 版本:3.6.0 data.table 版本:1.12.2

【问题讨论】:

  • 你能显示预期的输出吗
  • 当然,我已将其添加为使用 rev(x)[1L] 的输出。
  • 不是在dcast 中进行,您不能先进行子集化,然后进行 dcast
  • 我可以,是的,我会回到我的实际用例,看看是否有帮助。问题更多的是为什么使用 x[length(x)] 不能按预期工作。
  • 使用function(x) x[max(length(x), 1)]保证非零长度输出

标签: r data.table reshape2


【解决方案1】:

似乎data.table::dcast.data.table()reshape2::dcast() 都希望聚合函数为长度为 0 的输入返回长度为 1 的值。这两个函数都试图通过调用具有长度为 0 的参数的聚合函数来获取要使用的“默认值”。

data.table 代码的相关部分是here,如下所示:

fill.default = suppressWarnings(dat[0L][, eval(fun.call)])
if (nrow(fill.default) != 1L) stop(errmsg, call.=FALSE)

reshape2 从 plyr 调用 vaggregate(),它有类似的部分 here

.default <- .fun(.value[0], ...)

所以在x[length(x)]的情况下,两个函数获得的默认值本质上是:

last <- function(x) x[length(x)]
last(numeric())
#> numeric(0)

即长度为0的向量。但是这两个函数都要求默认值的长度为 1,因此会出错。

最后,dplyr::last() 起作用了,因为它为长度为 0 的输入返回 NA

dplyr::last(numeric())
#> [1] NA

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-21
    • 2013-07-10
    • 2019-05-13
    • 2012-01-03
    • 1970-01-01
    相关资源
    最近更新 更多