2013-03-21 137 views
5

這看起來應該很容易,但我無法弄清楚。如何用NA來替換data.table的整行?

>d=data.table(x=1:5,y=11:15,z=letters[1:5]) 
>d 
    x y z 
1: 1 11 a 
2: 2 12 b 
3: 3 13 c 
4: 4 14 d 
5: 5 15 e 

現在,我已經決定第3行是壞數據。我希望所有那些設置爲NA。

d[3,]<-NA 

警告消息: 在[<-.data.table*tmp*,3日,值= NA): 強迫 '邏輯' RHS到 '字符',以匹配列的類型。首先將目標列更改爲'邏輯'(通過創建一個新的邏輯'向量長度5(整個表的整數)'並分配該列; 即'替換'列),或者將RHS強制爲'字符'(例如1L , NA_ [real | integer] _,as。*等),以使您的意圖清晰,併爲 速度。或者,請在創建 表格時堅持正確設置列類型。

然而,它似乎工作。

> d 
    x y z 
1: 1 11 a 
2: 2 12 b 
3: NA NA NA 
4: 4 14 d 
5: 5 15 e 

如果我轉換爲data.frame,它也可以,但沒有警告。但後來我需要轉換回來,這似乎很尷尬。有沒有更好的辦法?

+1

如果你想設置的完整行'NA',爲什麼不乾脆刪除它? – Roland 2013-03-21 18:06:18

回答

7

使用顯式NA類型:

d[3,] <- list(NA_integer_, NA_integer_, NA_character_) 

另一種可能性:關於使用?set

d[3,] <- d[3,lapply(.SD,function(x) x[NA])] 
+2

這將複製整個data.table通過使用[< - – mnel 2013-03-21 21:33:27

3

什麼?

> d=data.table(x=1:5,y=11:15,z=letters[1:5]) 
> set(d, 3L, 1:3, NA_character_) 
> d 
    x y z 
1: 1 11 a 
2: 2 12 b 
3: NA NA NA 
4: 4 14 d 
5: 5 15 e 
> str(d) 
Classes ‘data.table’ and 'data.frame': 5 obs. of 3 variables: 
$ x: int 1 2 NA 4 5 
$ y: int 11 12 NA 14 15 
$ z: chr "a" "b" NA "d" ... 
- attr(*, ".internal.selfref")=<externalptr> 

或者,乾脆:

> d=data.table(x=1:5,y=11:15,z=letters[1:5]) 
> d[3] <- NA_character_ 
> str(d) 
Classes ‘data.table’ and 'data.frame': 5 obs. of 3 variables: 
$ x: int 1 2 NA 4 5 
$ y: int 11 12 NA 14 15 
$ z: chr "a" "b" NA "d" ... 
- attr(*, ".internal.selfref")=<externalptr> 

[馬太福音]是要麼set()是要走的路,或@ MNEL的回答很整齊:

DT[rownum, names(DT) := .SD[NA]] 

在在set方法中是否存在脅迫警告,以下是內部代碼(在此修改以傳達e突出點)。在寫這篇文章的時候,我似乎已經失去了精確性(從doubleinteger),以及強制RHS的低效率。

if((isReal(RHS) && (TYPEOF(targetcol)==INTSXP || isLogical(targetcol))) || 
    (TYPEOF(RHS)==INTSXP && isLogical(targetcol)) || 
    (isString(targetcol))) { 
    if (isReal(RHS)) s3="; may have truncated precision"; else s3=""; 
    warning("Coerced '%s' RHS to '%s' to match the column's type%s. ... <s3> ... 
} 

assign.c的完整的源代碼可以在這裏inpected:
https://r-forge.r-project.org/scm/viewvc.php/pkg/src/assign.c?view=markup&root=datatable

有改善這種高度相似的特性要求:

FR#2551 Singleton := RHS no coerce warning if no precision lost

是否添加有聯繫回到這個問題。

一般情況下,data.table在警告您潛在的問題或效率低下時會比較謹慎,在這種情況下,如果您想設置一組不同類型的列,則使用suppressWarnings()是另一種方式。

+0

我想這個答案只是掩蓋警告...通過手動做什麼警告似乎描述*它*自動做 – A5C1D2H2I1M1N2O1R2T1 2013-03-21 17:52:51

+0

我應該是一個更具體一點。希望能夠用任何一般的data.table來做到這一點,所以要做到這一點,我不得不查詢每列的類 – user1827975 2013-03-21 17:54:39

+0

不要使用'[<-'我很確定這會複製整個對象(即使對於data.tables ),這就是爲什麼':'和'set'被實現的原因。 – mnel 2013-03-21 21:41:13

0

這是我現在正在做的事情。好吧,我想但還是有點尷尬。

na_datatable_row<-function(dtrow){ 
    #take a row of data.table and return a row of the same table but 
    #with all values set tp NA 
    #DT[rownum,]<-NA works but throws an annoying warning 
    #so instead, do DT[rownum,]<-na_datatable_row(DT[anyrow,]) 
    #this preserves the right types 
    row=data.frame(dtrow) 
    row[1,]<-NA 
    return(data.table(row)) 
} 
8

要設置參考。

DT[rownum, (names(DT)) := lapply(.SD, function(x) { .x <- x[1]; is.na(.x) <- 1L; .x})] 

或許

DT[rownum, (names(DT)) := lapply(.SD[1,], function(x) { is.na(x) <- 1L; x})] 

這將確保正確的NA類型創建(因子和日期以及)

第二種情況只索引一次,這可能是稍快,如果DT中有許多列,或者rownum創建一個大的行子組。

你也可以做(上羅蘭的解決方案變體,但沒有複製。

DT[rownum, (names(DT)) := .SD[NA]] 
+0

+1。我想我需要更好地理解'data.table'製作副本等等。我最喜歡你最後的選擇。 – A5C1D2H2I1M1N2O1R2T1 2013-03-22 04:23:11

+3

實際上'DT [rownum,(names(DT)):= .SD [NA]]'很整潔!也許這比'set()'好,考慮一下。 – 2013-03-22 12:47:00