2012-05-06 6 views
22

sortkeyがあると、SASとSPSSのfirstlastの機能を複製するdata.tableのショートカットがありますか?グループ内の最初(または最後)のレコードにフラグを立てるためにdata.tableを使用

以下の歩行者のアプローチは、グループの最初のレコードにフラグを立てます。

私はゆっくりと馴染んでいるdata.tableの優雅さを考えれば、自分でショートカットを使っていると仮定しています。& multですが、まだ解明しようとしています。

はここに例を示します

require(data.table) 

set.seed(123) 
n <- 17 
DT <- data.table(x=sample(letters[1:3],n,replace=T), 
       y=sample(LETTERS[1:3],n,replace=T)) 
sortkey <- c("x","y") 
setkeyv(DT,sortkey) 
key <- paste(DT$x,DT$y,sep="-") 
nw <- c(T , key[2:n]!=key[1:(n-1)]) 
DT$first <- 1*nw 
DT 
+0

良い答えであってもよい:キー構築物は、しかし、各グループ内の最初のレコードの行インデックスを返す以下、です。テーブルソリューション:http://stats.stackexchange.com/questions/7884/fast-ways-in-r-to-get-the-first-row-of-a-data-frame-grouped-by-an-identifier/7889#7889 – Chase

+0

私はM.Dimoがグループの最初と最後を*抽出するのではなく、*ラベル付けすることを特に望んでいると思います。あなたが指しているリンクとOPが参照している 'マルチ'アプローチは、* label *ではなく* extract *をどのように表示するかを示しています。 –

答えて

21

data.tableを使用したソリューションのカップルです:

## Option 1 (cleaner solution, added 2016-11-29) 
uDT <- unique(DT) 
DT[, c("first","last"):=0L] 
DT[uDT, first:=1L, mult="first"] 
DT[uDT, last:=1L, mult="last"] 


## Option 2 (original answer, retained for posterity) 
DT <- cbind(DT, first=0L, last=0L) 
DT[DT[unique(DT),,mult="first", which=TRUE], first:=1L] 
DT[DT[unique(DT),,mult="last", which=TRUE], last:=1L] 

head(DT) 
#  x y first last 
# [1,] a A  1 1 
# [2,] a B  1 1 
# [3,] a C  1 0 
# [4,] a C  0 1 
# [5,] b A  1 1 
# [6,] b B  1 1 

これらの線のそれぞれに詰め多くは明らかにあります。ジョシュより

DT[unique(DT),,mult="first", which=TRUE] 
# [1] 1 2 3 5 6 7 11 13 15 
+0

あなたの答えをありがとう。私はこれがjoin& "first"を使って可能であったが、正しい構文を理解できなかったという感覚があった。そこにはっきりと説明されています。再度、感謝します。 –

+0

+1 'which'引数について知りたいです。 –

+0

ありがとう、皆さん。実際には、実際には@ PrasadChalasaniのアプローチのようなものを使用しています。しかし、これはたくさんの 'data.table'機能の素晴らしいデモであ​​ると思っていて、他の人が役に立つと思ってもらいたいと思っていました。また、(a)もっと良いdata.tableの解決策があるかどうか、(b) 'data.table '内のすべてのユニークなキーの組み合わせを抽出する' unique(DT) 'よりも良い方法があるならば、 '。 –

8

簡単な方法としては、duplicated()機能を使用することです。データフレームに適用すると、ベクトルフレームが生成されます。ベクトルは、データフレームを下に移動するときに行の値の組み合わせが前に発生していない場合にTRUEになります。 duplicated()を使用せずに

DT$first <- !duplicated(DT[, list(x,y) ])                                                          
DT$last <- rev(!duplicated(DT[, list(rev(x),rev(y)) ]))                                                      

> DT                                                                   
     x y first last                                                               
    [1,] a A TRUE TRUE                                                               
    [2,] a B TRUE TRUE                                                               
    [3,] a C TRUE FALSE                                                               
    [4,] a C FALSE TRUE                                                               
    [5,] b A TRUE TRUE                                                               
    [6,] b B TRUE TRUE                                                               
    [7,] b C TRUE FALSE                                                               
    [8,] b C FALSE FALSE                                                               
    [9,] b C FALSE FALSE                                                               
[10,] b C FALSE TRUE                                                               
[11,] c A TRUE FALSE                                                               
[12,] c A FALSE TRUE                                                               
[13,] c B TRUE FALSE                                                               
[14,] c B FALSE TRUE                                                               
[15,] c C TRUE FALSE                                                               
[16,] c C FALSE FALSE                                                               
[17,] c C FALSE TRUE    

もう一つの方法は次のとおりです。ここで

DT[ unique(DT), list(first = c(1, rep(0,length(y)-1)),                                                       
        last = c(rep(0,length(y)-1),1)) ]  

     x y first last                                                             
    [1,] a A  1 1                                                               
    [2,] a B  1 1                                                               
    [3,] a C  1 0                                                               
    [4,] a C  0 1                                                               
    [5,] b A  1 1                                                               
    [6,] b B  1 1                                                               
    [7,] b C  1 0                                                               
    [8,] b C  0 0                                                               
    [9,] b C  0 0                                                               
[10,] b C  0 1                                                               
[11,] c A  1 0                                                               
[12,] c A  0 1                                                               
[13,] c B  1 0                                                               
[14,] c B  0 1                                                               
[15,] c C  1 0                                                               
[16,] c C  0 0                                                               
[17,] c C  0 1   
+0

ありがとう!まだdata.tableの解決策については疑問がありますが、この場合は優雅さは間違いありません。 –

+0

歓迎します...私はちょうど別の方法でそれをやりました。あなたが参照している 'マルチ '機能は' DT' [i、j、mult = ...] 'の' i'引数に複数のマッチがある場合に最初か最後の(あるいはすべての) –

1

簡単な方法は、データを含むここで

unique(DT) 
unique(DT,fromLast=TRUE] 
関連する問題