为什么 dcast 不接受 x[length(x)]?
Why does dcast not accept x[length(x)]?
我一直在努力通过获取最后一个元素来使 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.
reshape2
版本的 dcast
也会发生这种情况,如果使用 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
正在迭代不在 table 中的 foo
值,并且不能存在于其他地方,因为 foo
是一个简单的字符向量,而不是因子向量。发生什么事了?
R
版本:3.6.0
data.table
版本:1.12.2
似乎 data.table::dcast.data.table()
和 reshape2::dcast()
都期望聚合函数 return 长度为 0 的输入的长度为 1 的值。这两个函数都尝试通过使用长度为 0 的参数调用聚合函数来获取要使用的 "default value"。
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()
起作用了,因为它 returns NA
对于长度为 0 的输入:
dplyr::last(numeric())
#> [1] NA
我一直在努力通过获取最后一个元素来使 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.
reshape2
版本的 dcast
也会发生这种情况,如果使用 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
正在迭代不在 table 中的 foo
值,并且不能存在于其他地方,因为 foo
是一个简单的字符向量,而不是因子向量。发生什么事了?
R
版本:3.6.0
data.table
版本:1.12.2
似乎 data.table::dcast.data.table()
和 reshape2::dcast()
都期望聚合函数 return 长度为 0 的输入的长度为 1 的值。这两个函数都尝试通过使用长度为 0 的参数调用聚合函数来获取要使用的 "default value"。
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()
起作用了,因为它 returns NA
对于长度为 0 的输入:
dplyr::last(numeric())
#> [1] NA