2017-05-08 55 views
0

我有以下data.table,與NA值和類型字符的非NA值的列如何在data.table列中標記/計數連續的非NA值對?

library(data.table) 
dt = fread(...) 

print(dt$column1) 

    [1] NA  NA  NA  "1 1" "1 1" "1 1" NA  NA  NA  NA                                                                
    [11] NA  "1 2" NA  NA  NA  NA  NA  NA  NA  NA                                                                
    [21] NA  NA  NA  NA  NA  NA  NA  NA  NA  NA                                                                
    [31] NA  NA  NA  NA  NA  "1 3" NA  NA  NA  NA                                                                
    [41] NA  "1 4" "1 4" NA  NA  NA  NA  NA  NA  NA                                                                
    [51] NA  NA  NA  NA  NA  NA  NA  NA  NA  NA                                                                
    [61] NA  NA  "1 5" NA  NA  NA  NA  NA  NA  NA                                                                
    ... 

我想其表示連續非NA值的標籤新的一列,即,

print(dt$groups) 

    [1] 0  0  0  1  1  1  0  0  0  0                                                                
    [11] 0  2  0  0  0  0  0  0  0  0                                                                
    [21] 0  0  0  0  0  0  0  0  0  0                                                                
    [31] 0  0  0  0  0  3  0  0  0  0                                                                
    [41] 0  4  4  0  0  0  0  0  0  0                                                               
    [51] 0  0  0  0  0  0  0  0  0  0                                                                
    [61] 0  0  5  0  0  0  0  0  0  0                                                                
    ... 

如果我試試這個:

dt[, groups := !is.na(column1)] 

這會給我一個布爾值向量,連續用真實的陳述。但我不確定如何將其轉換爲連續的TRUE對的標籤。

有沒有data.table方法來做到這一點?

+0

大概'DT [,組:= is.na(列1)* cumsum(!is.na(column1))]'會工作,但是很難在沒有[工作示例]的情況下測試代碼(http://stackoverflow.com/questions/5963269/how-to-make-a-great -r重現-例子)。 – lmo

+0

@lmo,不錯的嘗試。但是,這將爲前3個連續的非NA值分配不同的組ID。你錯過了一對圓括號:'(!is.na(column1))* cumsum(!is.na(column1))' – mt1022

+1

@ mt1022謝謝。就像我說的,如果沒有一個工作的例子,就很難測試代碼。 – lmo

回答

3

這裏是rle一個解決方案:

library(data.table) 
set.seed(1) 
dt <- data.table(column1 = sample(c(rep(NA, 3), '1'), 30, replace = T)) 

x <- rle(dt$column1) 
y <- cumsum(!is.na(x$values)) 
y[duplicated(y)] <- 0 
x$values <- y 
set(dt, NULL, 'group', inverse.rle(x)) 

# > dt 
#  column1 group 
# 1:  NA  0 
# 2:  NA  0 
# 3:  NA  0 
# 4:  1  1 
# 5:  NA  0 
# 6:  1  2 
# 7:  1  2 
# 8:  NA  0 
# 9:  NA  0 
# 10:  NA  0 
# 11:  NA  0 
# 12:  NA  0 
# 13:  NA  0 
# 14:  NA  0 
# 15:  1  3 
# 16:  NA  0 
# 17:  NA  0 
# 18:  1  4 
# 19:  NA  0 
# 20:  1  5 
# 21:  1  5 
# 22:  NA  0 
# 23:  NA  0 
# 24:  NA  0 
# 25:  NA  0 
# 26:  NA  0 
# 27:  NA  0 
# 28:  NA  0 
# 29:  1  6 
# 30:  NA  0 
# column1 group 

結合LMO的評論中,可以simpilied到:

x <- rle(dt$column1) 
x$values <- (!is.na(x$values)) * cumsum(!is.na(x$values)) 

set(dt, NULL, 'group', inverse.rle(x)) 
+0

感謝您的幫助。我沒有追蹤你的變量名稱:第一個代碼片段中的「x $ values」是什麼?我得到錯誤'x $ values中的錯誤:$運算符對於原子向量是無效的' – ShanZhengYang

+0

@ShanZhengYang,'x < - rle(dt $ column1)'將創建一個帶有rle類的列表。它有兩個元素:「長度」和「值」。 – mt1022

+0

我現在看到了錯誤。這工作完美,謝謝! – ShanZhengYang