使用by-operator拆分data.table:返回数值和/或NAs的函数失败

时间:2011-10-31 23:01:37

标签: r data.table

我有一个data.table,其中包含两列:一列ID列和一列value列。我想通过ID列拆分表,并在foo列上运行函数value。只要foo不返回NA,这样就可以正常工作。在那种情况下,我收到一个错误,告诉我组的类型不一致。我的假设是 - 由于is.logical(NA)等于TRUEis.numeric(NA)等于FALSEdata.table内部假定我想将逻辑值与数字值组合并返回错误。但是,我发现这种行为很特殊。对此有何评论?我是否会错过这里显而易见的事情或者确实是预期的行为?如果是这样,简短的解释就会很棒。 (请注意,我确实知道一个解决方法:让foo2返回一个完全不可能的数字并在以后过滤。但是,这似乎是错误的编码)。

以下是示例:

library(data.table)
foo1 <- function(x) {if (mean(x) < 5) {return(1)} else {return(2)}}
foo2 <- function(x) {if (mean(x) < 5) {return(1)} else {return(NA)}}
DT <- data.table(ID=rep(c("A", "B"), each=5), value=1:10)
DT[, foo1(value), by=ID] #Works perfectly
     ID V1
[1,]  A  1
[2,]  B  2
DT[, foo2(value), by=ID] #Throws error
Error in `[.data.table`(DT, , foo2(value), by = ID) : 
columns of j don't evaluate to consistent types for each group: result for group 2 has column 1 type 'logical' but expecting type 'numeric'

1 个答案:

答案 0 :(得分:11)

您可以通过指定您的函数应返回NA_real_而不是默认类型的NA来解决此问题。

foo2 <- function(x) {if (mean(x) < 5) {return(1)} else {return(NA)}}
DT[, foo2(value), by=ID] #Throws error
# Error in `[.data.table`(DT, , foo2(value), by = ID) : 
# columns of j don't evaluate to consistent types for each group: 
# result for group 2 has column 1 type 'logical' but expecting type 'numeric'

foo3 <- function(x) {if (mean(x) < 5) {return(1)} else {return(NA_real_)}}
DT[, foo3(value), by=ID] #Works
#      ID V1
# [1,]  A  1
# [2,]  B NA

顺便提一下foo2()失败时给出的信息非常有用。它基本上告诉你你的NA是错误的类型。要解决此问题,您只需要查找正确类型(或类)的NA常量:

NAs <- list(NA, NA_integer_, NA_real_, NA_character_, NA_complex_)
data.frame(contantName = sapply(NAs, deparse), 
           class       = sapply(NAs, class),
           type        = sapply(NAs, typeof))

#     contantName     class      type
# 1            NA   logical   logical
# 2   NA_integer_   integer   integer
# 3      NA_real_   numeric    double
# 4 NA_character_ character character
# 5   NA_complex_   complex   complex