TL;DR wrap median
和as.double()
median()
"向上跳"data.table是因为——即使只传递整数向量——median()
有时返回整数值,有时返回双精度.
## median of 1:3 is 2, of type "integer"
typeof(median(1:3))
# [1] "integer"
## median of 1:2 is 1.5, of type "double"
typeof(median(1:2))
# [1] "double"
用一个简单的例子再现错误消息:
library(data.table)
dt <- data.table(patients = c(1:3, 1:2),
weekdays = c("Mon", "Mon", "Mon", "Tue", "Tue"))
dt[,median(patients), by=weekdays]
# Error in `[.data.table`(dt, , median(patients), by = weekdays) :
# columns of j don't evaluate to consistent types for each group:
# result for group 2 has column 1 type 'double' but expecting type 'integer'
data.table人投诉,因为在判断了第一组要处理的值后,它得出结论,好的,这些结果将是"整数"类型.但是马上(或者在第4组中),它会被传递一个类型为"double"的值,该值不适合其"integer"结果向量.
data.table可以将结果累积到分组计算结束,然后在必要时执行类型转换,但这将需要大量额外的性能降低开销;相反,它只是报告发生了什么,并让您修复问题.第一个组运行后,它知道结果的类型,然后分配该类型的结果向量作为组数,然后填充它.如果以后发现某些组返回的项目超过1个,它将根据需要增加(即重新分配)结果向量.但在大多数情况下,data.table
对结果最终大小的第一次猜测是正确的(例如,每组1行结果),因此速度很快.
在这种情况下,使用as.double(median(X))
而不是median(X)
提供了一个合适的解决方案.
(顺便说一句,您使用round()
的版本是有效的,因为它总是返回"double"类型的值,您可以通过键入typeof(round(median(1:2))); typeof(round(median(1:3)))
看到这一点.)