我正在测试
data.table::groupingsets
,但我不断收到意外警告。
首先,我创建一个数据表用作输入:
## create "long" iris data set
long_iris <-melt(as.data.table(iris),
measure.vars = c('Sepal.Width', 'Sepal.Length', 'Petal.Width', 'Petal.Length'),
id.vars = 'Species',
variable.factor = FALSE,
value.factor = FALSE)
然后我将它作为参数传递给
groupingsets
:
groupingsets(long_iris,
.(N = .N,
Min = min(value),
Max = max(value),
Mean = mean(value),
SD = sd(value)),
by = c('Species', 'variable'),
## group by 'variable' and 'Species' separately as well as the interaction, plus the overall stats (character())
sets = list('variable', 'Species', c('variable', 'Species'), character()))
结果看起来不错
Species variable N Min Max Mean SD
1: <NA> Sepal.Width 150 2.0 4.4 3.057333 0.4358663
2: <NA> Sepal.Length 150 4.3 7.9 5.843333 0.8280661
3: <NA> Petal.Width 150 0.1 2.5 1.199333 0.7622377
4: <NA> Petal.Length 150 1.0 6.9 3.758000 1.7652982
5: setosa <NA> 200 0.1 5.8 2.535500 1.8483429
6: versicolor <NA> 200 1.0 7.0 3.573000 1.7623850
7: virginica <NA> 200 1.4 7.9 4.285000 1.9153899
8: setosa Sepal.Width 50 2.3 4.4 3.428000 0.3790644
9: versicolor Sepal.Width 50 2.0 3.4 2.770000 0.3137983
10: virginica Sepal.Width 50 2.2 3.8 2.974000 0.3224966
11: setosa Sepal.Length 50 4.3 5.8 5.006000 0.3524897
12: versicolor Sepal.Length 50 4.9 7.0 5.936000 0.5161711
13: virginica Sepal.Length 50 4.9 7.9 6.588000 0.6358796
14: setosa Petal.Width 50 0.1 0.6 0.246000 0.1053856
15: versicolor Petal.Width 50 1.0 1.8 1.326000 0.1977527
16: virginica Petal.Width 50 1.4 2.5 2.026000 0.2746501
17: setosa Petal.Length 50 1.0 1.9 1.462000 0.1736640
18: versicolor Petal.Length 50 3.0 5.1 4.260000 0.4699110
19: virginica Petal.Length 50 4.5 6.9 5.552000 0.5518947
20: <NA> <NA> 600 0.1 7.9 3.464500 1.9754900
但我也收到以下警告:
Warning messages:
1: In min(value) : no non-missing arguments to min; returning Inf
2: In max(value) : no non-missing arguments to max; returning -Inf
我使用的是鸢尾花数据框,因此没有缺失值。我知道这些错误通常是由于将 0 长度向量传递给
min
或 max
引起的,但我不明白这是如何发生的。
我得到了预期的结果,但我不明白为什么会收到此警告。
这就是它试图做的事情,尽管我不知道“为什么”它以这种方式实现背后的故事。
编辑:来自@jangorecki,
data.table
的长期贡献者。感谢您的参与!
创建模板DT,绑定其他分组
我们提供一个调试功能:
groupingsets(long_iris,
.(N = .N, Max = (function(z) { browser(); max(value); })(value)),
by = c('Species', 'variable'),
## group by 'variable' and 'Species' separately as well as the interaction, plus the overall stats (character())
sets = list(character(), 'variable', 'Species', c('variable', 'Species')))
在第一个实例化中,让我们看一下
where
和堆栈上的前几个函数:
Browse[2]> where
where 1: (function(z) {
browser()
max(value)
})(value)
where 2: `[.data.table`(x, 0L, eval(jj), by)
where 3: x[0L, eval(jj), by]
和第二次迭代
Browse[2]> c
Browse[2]> where
where 1: (function(z) {
browser()
max(value)
})(value)
where 2: eval(jsub, SDenv, parent.frame())
where 3: eval(jsub, SDenv, parent.frame())
请注意,在第一次调用时,我们看到
x[0L, eval(jj), by]
,这是故意使用 0 行帧进行调用。
我怀疑(其中一个
data.table
-devs会通过管道输入吗?)这是为了查找一行的类,所以我们至少会返回something。在来源中找到这个有点令人鼓舞:
empty = if (length(.SDcols)) x[0L, eval(jj), by, .SDcols=.SDcols] else x[0L, eval(jj), by]
这不会发生在
sum
上,可能是因为它们在没有数据的情况下表现得有些不同:
min()
# Warning in min() : no non-missing arguments to min; returning Inf
# [1] Inf
sum()
# [1] 0
如果您知道要使用的函数带有空数据(例如
min
和 max
),您可以随时抑制它们或定义具有合理默认值的空友好版本(例如 -Inf
代表 max
,以及 Inf
表示 min
):
max2 <- function(x, ...) max(c(-Inf, x), ...)
那就不吵了:
groupingsets(long_iris,
.(N = .N, Max = max2(value)),
by = c('Species', 'variable'),
sets = list(character(), 'variable', 'Species', c('variable', 'Species')))
# Species variable N Max
# <fctr> <char> <int> <num>
# 1: <NA> <NA> 600 7.9
# 2: <NA> Sepal.Width 150 4.4
# 3: <NA> Sepal.Length 150 7.9
# 4: <NA> Petal.Width 150 2.5
# 5: <NA> Petal.Length 150 6.9
# 6: setosa <NA> 200 5.8
# 7: versicolor <NA> 200 7.0
# 8: virginica <NA> 200 7.9
# 9: setosa Sepal.Width 50 4.4
# 10: versicolor Sepal.Width 50 3.4
# 11: virginica Sepal.Width 50 3.8
# 12: setosa Sepal.Length 50 5.8
# 13: versicolor Sepal.Length 50 7.0
# 14: virginica Sepal.Length 50 7.9
# 15: setosa Petal.Width 50 0.6
# 16: versicolor Petal.Width 50 1.8
# 17: virginica Petal.Width 50 2.5
# 18: setosa Petal.Length 50 1.9
# 19: versicolor Petal.Length 50 5.1
# 20: virginica Petal.Length 50 6.9
# Species variable N Max