【问题标题】:Splitting a data.table with the by-operator: functions that return numeric values and/or NAs fail使用 by-operator 拆分 data.table:返回数值和/或 NA 的函数失败
【发布时间】:2011-12-19 03:14:38
【问题描述】:

我有一个包含两列的data.table:一列ID,一列value。我想按ID 列拆分表并在value 列上运行函数foo。只要foo 不返回 NA,这就可以正常工作。在这种情况下,我收到一个错误,告诉我组的类型不一致。我的假设是 - 因为is.logical(NA) 等于TRUEis.numeric(NA) 等于FALSEdata.table 在内部假设我想将逻辑值与数字值组合并返回错误。但是,我发现这种行为很奇怪。有cmet吗?我是否错过了一些明显的东西,或者这确实是预期的行为?如果是这样,简短的解释会很棒。 (请注意,我确实知道一种解决方法:让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'

【问题讨论】:

    标签: r data.table


    【解决方案1】:

    您可以通过指定您的函数应返回 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
    

    【讨论】:

    • 我与R 合作的次数越多,我就越意识到我不知道的东西有多少。这个“NA_real_”技巧绝对是其中之一。所以感谢@Josh O'Brien,很好的回答。
    • 谢谢。我在答案中添加了更多关于NA 常量的信息,因为这对我来说通常很有用,而且它是NA 值的一个方面,通常对用户来说是不可见的。这是应该的!
    • 如果你不提前知道课程怎么办?使用 by= 参数时,在 data.table 中对我来说是个大问题。你遇到过这样的问题吗?
    • @rbatt 在这种情况下的解决方案(如果我正确理解您的问题)将确保应用于每个 by 组的函数返回的结果始终属于同一类型。 Here is an example that might help you see what I mean。特别是向下滚动到我在对as.double() 的调用中结束对median(X) 的调用(有时会产生"integer",有时会产生"numeric" 类对象)的部分,以确保结果始终具有类"numeric".
    • @JoshO'Brien Gotcha,谢谢。那么你会建议只使用switch(class(x), double = as.numeric(...), character = as.character(...), ... 类型的方法吗?对于某些功能,很明显它应该是特定类型。我使用了一个以unique 为核心的函数,因此输出可以是任何类。我最终做了一个解决方法,所以我不必指定返回的 NA 类型(只允许unique() 为我做这件事)。但它仍然向我提出了这个问题。我可以创建一个更详细的新问题。
    猜你喜欢
    • 1970-01-01
    • 2017-08-19
    • 2021-06-27
    • 1970-01-01
    • 2018-06-10
    • 2012-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多