7

我在聚合时遇到了 data.table 的以下问题,使用 .SD 并指定 lapply 并明确说明来自 lapply 的 FUN 参数。这是出乎意料的行为还是我只是错过了一些东西。为什么我不能在 lapply 中明确说明 FUN?以下是一个可重现的示例。

require(data.table)
dt <- as.data.table(iris)
dt$Sepal.Length[sample(1:nrow(dt), 10)] <- NA
dt[, lapply(.SD, function(x) sum(!is.na(x), na.rm=TRUE)), by = Species]
      Species Sepal.Length Sepal.Width Petal.Length Petal.Width
1:     setosa           47          50           50          50
2: versicolor           46          50           50          50
3:  virginica           47          50           50          50
dt[, lapply(.SD, FUN=function(x) sum(!is.na(x), na.rm=TRUE)), by = Species]
Error in ..FUN(FUN = Sepal.Length) : 
  unused argument(s) (FUN = Sepal.Length)

更新:

归档为错误:#4839。(Arun 的修复现在在 v1.8.9 中)

4

1 回答 1

8

我不认为你缺少任何东西。您可能应该在此处提交一个链接到此帖子的错误。接得好!

发生这种情况是因为,当您使用lapplywith .SD(in j) 时,如果可能的话,data.table会尝试查找是否有办法优化函数调用导致的开销。但是,在这个过程中,而不是调用函数:

..FUN(Sepal.Length)

其中..FUN = function(x) sum(!is.na(x), na.rm=TRUE),它变成:

..FUN(FUN = Sepal.Length)

由于该函数没有调用参数FUN,因此返回错误。您可以通过在函数调用中更改x为来验证这一点:FUN

dt[, lapply(.SD, FUN=function(FUN) sum(!is.na(FUN), na.rm=TRUE)), by = Species]
#       Species Sepal.Length Sepal.Width Petal.Length Petal.Width
# 1:     setosa           49          50           50          50
# 2: versicolor           44          50           50          50
# 3:  virginica           47          50           50          50

内部:通过查看[.data.table函数,解决此问题的一种方法是重写该行:

txt <- as.list(jsub)[-1L]
# [[1]]
# .SD

# $FUN <~~~~ this name FUN gets caught up in building the expression later
# function(x) sum(!is.na(x), na.rm = TRUE)

和:

txt <- as.list(jsub)[-1L]
names(txt)[2] <- ""
# [[1]]
# .SD

# [[2]]
# function(x) sum(!is.na(x), na.rm = TRUE)

运行CHECK成功完成。

于 2013-08-19T14:01:33.610 回答