4

があり、data.tableさまざまな行の場所から開始して同じ長さのセグメントを抽出する必要があります。これを行う最も簡単な方法は何ですか?例えば:

x <- data.table(a=sample(1:1000,100), b=sample(1:1000,100))
r <- c(1,2,10,20,44)
idx <- lapply(r, function(i) {j <-which(x$a == i); if (length(j)>0) {return(j)} })
y <- lapply(idx, function(i) {if (!is.null(i)) x[i:(i+5)]})
do.call(rbind, y)
    a   b
1:  44  63
2:  96 730
3: 901 617
4: 446 370
5: 195 341
6: 298 411

これは確かdata.tableに物事を行う方法ではないので、私はもっと良い方法があることを望んでいましたか?

編集:以下のコメントに従って、これを編集します。これは、の値aが必ずしも連続しているとは限らず、行番号に対応しているとは限らないことを明確にするためです。

4

2 に答える 2

6

行の位置をすでに知っているかどうか、またはそれらを検索するかどうかはわかりません。いずれにせよ、これは両方をカバーする必要があります。

require(data.table)
set.seed(1)
DT = data.table(a=sample(1:1000,20), b=sample(1:1000,20))
setkey(DT,a)
DT
#       a   b
#  1:  62 338
#  2: 175 593
#  3: 201 267
#  4: 204 478
#  5: 266 935
#  6: 372 212
#  7: 374 711
#  8: 380 184
#  9: 491 659
# 10: 572 651
# 11: 625 863
# 12: 657 380
# 13: 679 488
# 14: 707 782
# 15: 760 816
# 16: 763 404
# 17: 894 385
# 18: 906 126
# 19: 940  14
# 20: 976 107
r = c(201,380,760)
starts = DT[J(r),which=TRUE]  # binary search for items
                              # skip if the starting row numbers are known
starts
# [1]  3  8 15

オプション1:行番号シーケンスを作成し、連結して、1回のルックアップを実行しDTます(行番号で選択するためだけにキーやバイナリ検索は必要ありません):

DT[unlist(lapply(starts,seq.int,length=5))]
#       a   b
#  1: 201 267
#  2: 204 478
#  3: 266 935
#  4: 372 212
#  5: 374 711
#  6: 380 184
#  7: 491 659
#  8: 572 651
#  9: 625 863
# 10: 657 380
# 11: 760 816
# 12: 763 404
# 13: 894 385
# 14: 906 126
# 15: 940  14

オプション2: data.tableサブセットのリストを作成し、rbindそれらを一緒に作成します。これはオプション1よりも効率的ではありませんが、完全を期すために:

L = lapply(starts,function(i)DT[seq.int(i,i+4)])
L
# [[1]]
#      a   b
# 1: 201 267
# 2: 204 478
# 3: 266 935
# 4: 372 212
# 5: 374 711
# 
# [[2]]
#      a   b
# 1: 380 184
# 2: 491 659
# 3: 572 651
# 4: 625 863
# 5: 657 380
# 
# [[3]]
#      a   b
# 1: 760 816
# 2: 763 404
# 3: 894 385
# 4: 906 126
# 5: 940  14 


rbindlist(L)   # more efficient that do.call("rbind",L). See ?rbindlist.
#       a   b
#  1: 201 267
#  2: 204 478
#  3: 266 935
#  4: 372 212
#  5: 374 711
#  6: 380 184
#  7: 491 659
#  8: 572 651
#  9: 625 863
# 10: 657 380
# 11: 760 816
# 12: 763 404
# 13: 894 385
# 14: 906 126
# 15: 940  14
于 2012-09-02T22:07:19.123 に答える
1

これはより良い方法であると思います。data.tableの10分間の紹介によると、これはバイナリ検索であるため、次のようになります。

library(data.table)
x <- data.table(a=1:100, b=1:100, key="a")
r <- c(1,2,10,20,44)
vec <- numeric()
for (elem in r) {
  vec <- c(vec, seq(from=elem, by=1, length.out=6))
}
x[data.table(vec)]
     a  b
 1:  1  1
 2:  2  2
 3:  3  3
 4:  4  4
 5:  5  5
 6:  6  6
 7:  2  2
...

最初に列aをキーとして設定し、次にその列aと結合する内部data.tableを作成することに注意してください。の作成vecはおそらく最善の方法ではありませんが、それがボトルネックになることはありません。

于 2012-09-02T15:47:57.017 に答える