web-dev-qa-db-ja.com

data.tableのサブセット

Data.table(パッケージ data.table から)をRで(data.frameではなく)サブセット化しようとしています。 4桁の年をキーにしています。何年かかけてサブセット化したいと思います。たとえば、1999年、2000年、2001年のすべてのレコードを取得したいとします。

私のDT[J(year)]バイナリ検索構文を次のように渡してみました:

1999,2000,2001
c(1999,2000,2001)
1999, 2000, 2001

しかし、これらはどれも機能していないようです。選択したい年が1年だけでなく複数年であるサブセットを実行する方法を知っている人はいますか?

17
exl

data.framesで機能するものはdata.tablesで機能します。

subset(DT, year %in% 1999:2001)
19
Richie Cotton

質問は明確ではなく、使用するのに十分なデータを提供しませんが、それは役に立ちます。そのため、今後提供するデータで編集できる人がいれば歓迎します。投稿のタイトルも記入できます。MatthewDowleは、しばしば2つのベクトルのサブセット化の質問に回答しますが、1つのベクトルのサブセットに一致するステートメントのサブセッティングにそれほど頻繁に回答することはありません。私はしばらくの間、文字ベクトルの1つを見つけるまで、答えを探していました here

このデータを考えてみましょう:

_library(data.table)
n <- 100
X <- data.table(a=sample(c(10,20,25,30,40),n,replace=TRUE),b=1:n)
_

X[X$a %in% c(10,20),]に対応するdata.tableスタイルのクエリは、なんとなく驚くべきものです。

_setkey(X,a)
X[.(c(10,20))]
X[.(10,20)] # works for characters but not for integers
            # instead, treats 10 as the filter
            # and 20 as a new variable

# for comparison :
X[X$a %in% c(10,20),]
_

さて、どれが一番いいですか?キーがすでに設定されている場合は、data.tableを使用します。それ以外の場合は、次の時間測定を証明するために、そうでない可能性があります(私の1,75 Go RAM computer):

_n <- 1e7
X <- data.table(a=sample(c(10,20,25,30,40),n,replace=TRUE),b=1:n)
system.time(X[X$a %in% c(10,20),])
# utilisateur     système      écoulé (yes, I'm French) 
#        1.92        0.06        1.99
system.time(setkey(X,a))
# utilisateur     système      écoulé 
#       34.91        0.05       35.23 
system.time(X[J(c(10,20))])
# utilisateur     système      écoulé 
#        0.15        0.08        0.23
_

しかし、多分マシューはより良い解決策を持っています...


[マシュー] numeric(別名double)のソートタイプがintegerよりも遅いことを発見しました。長年、ユーザーがこの罠に陥り、このようなひどいタイミングを報告するのを恐れて、doubleをキーに含めることを許可しませんでした。 doubleには高速ソートがまだ実装されていないため、多少の不安を伴うキーでdoubleを許可しました。 integerおよびcharacterの高速ソートは、カウントソートを使用して行われるため、非常に優れています。 うまくいけば、いつかnumericで高速ソートできます! (実装済み-以下を参照)。

1.9.0より前のdata.tableのタイミング

_n <- 1e7
X <- data.table(a=sample(c(10,20,25,30,40),n,replace=TRUE),b=1:n)      
system.time(setkey(X,a))
#   user  system elapsed 
# 13.898   0.138  14.216 

X <- data.table(a=sample(as.integer(c(10,20,25,30,40)),n,replace=TRUE),b=1:n)
system.time(setkey(X,a))
#   user  system elapsed 
#  0.381   0.019   0.408 
_

_2_がデフォルトでRのタイプnumericであることを覚えておいてください。 _2L_はintegerです。 _data.table_はnumericを受け入れますが、それでもintegerを優先します。


数値の高速基数ソートは、v1.9.0以降で実装されています。

V1.9.0以降

_n <- 1e7
X <- data.table(a=sample(c(10,20,25,30,40),n,replace=TRUE),b=1:n)      
system.time(setkey(X,a))
#    user  system elapsed 
#   0.832   0.026   0.871 
_
15
Arthur

上記と同様ですが、より多くのdata.table esque:

DT[year %in% c(1999, 2000, 2001)]

8
Yike Lu

これで動作します:

sample_DT = data.table(year = rep(1990:2010, length.out = 1000), 
                       random_number = rnorm(1000), key = "year")
year_subset = sample_DT[J(c(1990, 1995, 1997))]

同様に、既存のdata.tableにsetkey(existing_DT、year)でキーを設定してから、上記のようにJ()構文を使用できます。

問題は、最初にデータをキー入力しなかったことにあると思います。

1
Taylor White