1

入力と同じ列名を持つデータ テーブルのリストを取得し、以下に示すように、連続した rbind を使用して結合された各データ フレームからの一意の行を持つ単一のデータ テーブルを返す関数に取り組んでいます。

関数は「非常に」大きなdata.table(数千万行)に適用されるため、それをいくつかの小さなデータテーブルに分割し、それらをリストに割り当てて再帰を使用する必要がありました。データ テーブルのリストの長さ (奇数または偶数) に応じて各ステップで、そのリスト インデックスで data.table の一意を見つけ、リスト インデックス x - 1 でデータ テーブルを見つけ、次に 2 を連続して rbind して割り当てます。インデックス x - 1 をリストするには、さらにインデックス x をリストします。

最終的なunique-d data.tableを印刷すると生成できますが(たとえば、print(listelement [[1]])、(listelement [[1]])を返すと、明らかに何かが欠けているに違いありません。 get NULL.誰かが私が欠けているものを見つけることができれば助けになるでしょう...または、おそらくこれを実行するための他のより効率的な方法があるかどうかを提案します.

また、各 data.table をリストに追加する代わりに、リストに「参照」として追加できますか? list(datatable1, datatable2 ...) のようなことをすると、実際にそれらがコピーされると思いますか?

## CODE
returnUnique2 <- function (alist) {

if (length(alist) == 1) {
  z <- (alist[[1]])
  print (class(z))
  print (z)   ### This is the issue, if I change to return (z), I get NULL (?)
}

if (length(alist) %% 2 == 0) {
  alist[[length(alist) - 1]] <- unique(rbind(unique(alist[[length(alist)]]), unique(alist[[length(alist) - 1]])))
  alist[[length(alist)]] <- NULL
  returnUnique2(alist)
}

if (length(alist) %% 2 == 1 && length(alist) > 2) {
  alist[[length(alist) - 1]] <- unique(rbind(unique(alist[[length(alist)]]), unique(alist[[length(alist) - 1]])))
  alist[[length(alist)]] <- NULL
  returnUnique2(alist)
}  
}


## OUTPUT with print statement
t1 <- data.table(col1=rep("a",10), col2=round(runif(10,1,10)))
t2 <- data.table(col1=rep("a",10), col2=round(runif(10,1,10)))
t3 <- data.table(col1=rep("a",10), col2=round(runif(10,1,10)))
tempList <- list(t1, t2, t3)

returnUnique2(tempList)

[1] "list"
[[1]]
col1 col2
 1:    a    3
 2:    a    2
 3:    a    5
 4:    a    9
 5:    a   10
 6:    a    7
 7:    a    1
 8:    a    8
 9:    a    4
10:    a    6

以下を変更すると、

print (z)   ### This is the issue, if I change to return (z), I get NULL (?)

読む

return(z)

NULL を返します

前もって感謝します。

4

3 に答える 3

1

forこれはループの良い使用例のようです。行数が多い場合、ループを使用するオーバーヘッドはfor、計算時間に比べて比較的小さいはずです。私は自分data.tableのをリストに組み合わせて(ll私の例で呼び出されます)、次に重複した行をそれぞれ削除rbindし、次に一意の行で前の行に移動data.tableし、一意の行で再度サブセット化します。

各チャンクに多くの重複行がある場合、これにより時間が節約される可能性があります。全体として、それがどれほど効果的かはわかりませんが、試してみる価値はありますか?

#  Create empty data.table for results (I have columns x and y in this case)
res <- data.table( x= numeric(0),y=numeric(0))

#   loop over all data.tables in a list called 'll'
for( i in 1:length(ll) ){
    #  rbind the unique rows from the current list element to the results from all previous iterations
    res <- rbind( res , ll[[i]][ ! duplicated(ll[[i]]) , ] )
    #  Keep only unique records at each iteration
    res <- res[ ! duplicated(res) , ]
}

別の注意として、のドキュメントを見ましたdata.tableか? それは明示的に述べています、

通常、data.tables はキーでソートされるため、重複のテストは特に迅速です。

だから、data.table全体で実行したほうがいいかもしれませんか?

DT[ ! duplicated(DT) , ]
于 2013-06-22T21:46:32.697 に答える
0

各 data.table に id 列を追加します

t1$id=1
t2$id=2
t3$id=3

次に、それらを一度に組み合わせて、 を使用して一意にしby=ます。data.tables が巨大な場合は、unique を呼び出す前に setkey(...) を使用して id にインデックスを作成できます。

tall=rbind(t1,t2,t3)
tall[,unique(col1,col2),by=id]
于 2013-06-22T18:16:35.187 に答える