2016-06-09 47 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,我的愚蠢。我正在通过数据帧的方式。在一段时间内编辑我的答案。 –

相关问题