2011-10-31 25 views
11

我有一個data.table,它有兩列:一列爲ID列,另一列爲value列。我想通過ID列將表拆分,並在value列上運行函數foo。只要foo不返回NAs,此工作正常。在這種情況下,我收到一個錯誤,告訴我組的類型不一致。我的假設是 - 因爲is.logical(NA)等於TRUEis.numeric(NA)等於FALSEdata.table內部假定我想將邏輯值與數字值合併並返回錯誤。但是,我發現這種行爲是奇特的。對此有何評論?我在這裏錯過了一些明顯的東西,或者確實是有意的行爲?如果是這樣,一個簡短的解釋會很好。 (請注意,我知道一個解決方法:讓foo2返回一個完全不可能的數字,然後過濾,但這看起來好像是不好的編碼)。用by-operator分割data.table:返回數值和/或NAs的函數失敗

這裏是例子:

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' 

回答

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 
+1

我越用'R'工作,我越來越意識到有多少東西,我只是不知道。這個'NA_real_'技巧絕對是其中之一。所以謝謝@Josh O'Brien,很好的回答。 –

+0

謝謝。我在回答中加入了更多關於「常量」的常量,因爲這對我來說常常很有用,而且這是用戶通常看不見的「NA」值的一個方面。這是應該的! –

+0

如果您提前不知道該怎麼辦?使用'by ='參數時,data.table對我來說是個大問題。你遇到過這樣的問題嗎? – rbatt

相關問題