2

概要

文字列の行名と互いに素なセットのリスト(n = 20,000+)を含む大きな(nrows> 5,000,000+)データフレームAを指定します。ここで、各セットはA行名で構成されます。これを作成するのに最適な方法は何ですか。一意の値を介してBのセットを表すベクトル?

以下は、この問題を説明する例です。

# Input
A <- data.frame(d = rep("A", 5e6), row.names = as.character(sample(1:5e6)))
B <- list(c("4655297", "3177816", "3328423"), c("2911946", "2829484"), ...) # Size 20,000+

望ましい結果は次のようになります。

# An index of NA represents that the row is not part of any set in B.
> A[,"index", drop = F]
        d index
4655297 A     1
3328423 A     1
2911946 A     2
2829484 A     2
3871770 A    NA
2702914 A    NA
2581677 A    NA
4106410 A    NA
3755846 A    NA
3177816 A     1

ナイーブな試み

このようなことは、次の方法を使用して実現できます。

n <- 0
A$index <- NA
lapply(B, function(x){
  n <<- n + 1
  A[x, "index"] <<- n
})

問題

ただし、これはAを複数回インデックス付けするため、不当に遅く(数時間)、R風またはエレガントではありません。

望ましい結果を迅速かつ効率的に生成するにはどうすればよいですか?

4

1 に答える 1

4

これは、現在の方法と比較してそれほど悪くないベースを使用する提案です。

サンプルデータ:

A <- data.frame(d   = rep("A", 5e6),
                set = sample(c(NA, 1:20000), 5e6, replace = TRUE),
                row.names = as.character(sample(1:5e6)))
B <- split(rownames(A), A$set)

基本方法:

system.time({
A$index <- NA
A[unlist(B), "index"] <- rep(seq_along(B), times = lapply(B, length))
})
#    user  system elapsed 
#   15.30    0.19   15.50 

小切手:

identical(A$set, A$index)
# TRUE

もっと速いものなら、data.table重宝すると思います。

于 2012-10-23T19:37:27.567 に答える