2016-06-09 58 views
3

我有一個data.table,其中有許多缺失值,我想要一個變量,它爲每組中的第一個非missin值給出1。R:在data.table列中按組找到第一個非NA觀察值

說我有這樣的data.table:

library(data.table) 
DT <- data.table(iris)[,.(Petal.Width,Species)] 
DT[c(1:10,15,45:50,51:70,101:134),Petal.Width:=NA] 

現在有missings之初,在月底之間。我已經嘗試了兩個版本,一個是:

DT[min(which(!is.na(Petal.Width))),first_available:=1,by=Species] 

但只發現了全球最小的(在這種情況下,setosa得到正確1)組,而不是最低。我認爲這是因爲data.table我的第一個子集,然後按組排序,正確嗎?因此,它只適用於全球最小值爲which(!is.na(Petal.Width))的行,這是第一個非NA值。

在j處的測試第二次嘗試:

DT[,first_available:= ifelse(min(which(!is.na(Petal.Width))),1,0),by=Species] 

剛剛返回1組成的柱。在這裏,我沒有一個很好的解釋,爲什麼它不起作用。

我的目標是:

DT[,first_available:=0] 
DT[c(11,71,135),first_available:=1] 

但在現實中我有數百個組。任何幫助,將不勝感激!

編輯:this問題確實接近,但沒有針對NA的問題,如果我理解正確的話,並不能解決問題。我想:

DT <- data.table(DT, key = c('Species')) 
DT[unique(DT[,key(DT), with = FALSE]), mult = 'first'] 
+2

可能的複製Ø f [R:通過使用data.table和自聯接的組首次觀察](http://stackoverflow.com/questions/15776064/r-first-observation-by-group-using-data-table-self-join) – mtoto

+0

請參閱編輯,我不確定 –

回答

6

這裏有一種方法:

DT[!is.na(Petal.Width), first := as.integer(seq_len(.N) == 1L), by = Species] 
+0

不錯,這個也保存在NA之間,這可能會得心應手 –

+0

嘿,你好,你能解釋一下這部分代碼嗎?seq_len(.N)' –

+1

'.N'是一個特殊的符號,觀察每個組。而'seq_len'構造一個從1到.N的序列。有關'.N'和其他特殊符號的信息,請參閱'?data.table',更多信息請參閱'?seq_len'。 – Arun

2

我們可以嘗試

DT[DT[, .I[which.max(!is.na(Petal.Width))] , Species]$V1, 
    first_available := 1][is.na(first_available), first_available := 0] 

或者稍微更緊湊的選擇是

DT[, first_available := as.integer(1:nrow(DT) %in% 
     DT[, .I[!is.na(Petal.Width)][1L], by = Species]$V1)][] 
+1

很好,這是我正在尋找的。我會趕上。我和1L –

-1
> DT[!is.na(DT$Petal.Width) & DT$first_available == 1] 
    #  Petal.Width Species first_available 
    # 1:   0.2  setosa    1 
    # 2:   1.8 versicolor    1 
    # 3:   1.4 virginica    1 

    > rownames(DT)[!is.na(DT$Petal.Width) & DT$first_available == 1] 
    # [1] "11" "71" "135" 

    > rownames(DT)[!is.na(DT$Petal.Width) & DT$first_available == 0] 
    # [1] "12" "13" "14" "16" "17" "18" "19" "20" "21" "22" "23" "24" 
    # [13] "25" "26" "27" "28" "29" "30" "31" "32" "33" "34" "35" "36" 
    # [25] "37" "38" "39" "40" "41" "42" "43" "44" "72" "73" "74" "75" 
    # [37] "76" "77" "78" "79" "80" "81" "82" "83" "84" "85" "86" "87" 
    # [49] "88" "89" "90" "91" "92" "93" "94" "95" "96" "97" "98" "99" 
    # [61] "100" "136" "137" "138" "139" "140" "141" "142" "143" "144" "145" "146" 
    # [73] "147" "148" "149" "150" 
+1

但這假設我已經有了答案,不是嗎? 'first_available'就是我想要得到的,我只是在最後手動構建它來展示我的目標。 –

+1

另外,混合'data.table'和'data.frame'語法是不是糟糕的風格?爲了簡單起見,我偶爾會這樣做,所以我不確定。你怎麼看? –

+1

哎呀,只是檢查。我正在嘗試你的first_available,然後是DT,我的愚蠢。我正在通過數據幀的方式。在一段時間內編輯我的答案。 –

相關問題