12

リストにたくさんの data.tables があります。リスト内の各 data.tableに適用したいのですunique()が、そうするとすべての data.table キーが破棄されます。

次に例を示します。

A <- data.table(a = rep(c("a","b"), each = 3), b = runif(6), key = "a")
B <- data.table(x = runif(6), b = runif(6), key = "x")

blah <- unique(A)

ここにはblahまだ鍵があり、すべてが正しいです。

key(blah)

# [1] "a"

しかし、data.tables をリストに追加して使用するlapply()と、キーが破棄されます。

dt.list <- list(A, B)

unique.list <- lapply(dt.list, unique) # Keys destroyed here

lapply(unique.list, key) 

# [[1]]
# NULL

# [[2]]
# NULL

これはおそらく、キーが「参照によって」割り当てられることの意味をよく理解していないことに関係しています。キーが消えるという他の問題があったからです。

そう:

  • lapply が鍵を保持しないのはなぜですか?
  • キーが「参照によって」割り当てられるとはどういう意味ですか?
  • リストにdata.tablesを保存する必要がありますか?
  • キーを失うことを恐れずに data.tables を安全に保存/操作するにはどうすればよいですか?

編集:

価値があるのは、恐ろしいforループも問題なく機能することです。

unique.list <- list()

for (i in 1:length(dt.list)) {
  unique.list[[i]] <- unique(dt.list[[i]])
}

lapply(unique.list, key)

# [[1]]
# [1] "a"

# [[2]]
# [1] "x"

しかし、これは R であり、forループはです。

4

2 に答える 2

9

Interestingly, notice the difference between these two different results

lapply(dt.list, unique) 
lapply(dt.list, function(x) unique(x)) 

If you use the latter, the results are as you would expect.


The seemingly unexpected behavior is due to the fact that the first lapply statement is invoking unique.data.frame (ie from {base}) while the second is invoking unique.data.table

于 2013-02-18T02:00:16.057 に答える
6

良い質問。文書化されていることがわかりました?lapply(注セクションを参照):

歴史的な理由から、lapply によって作成された呼び出しは評価されておらず、これに依存するコード (bquote など) が書かれています。これは、記録された呼び出しが常に FUN(X[[0L]], ...) の形式であり、0L が現在の整数インデックスに置き換えられることを意味します。これは通常は問題になりませんが、FUN が sys.call または match.call を使用する場合、または呼び出しを使用するプリミティブ関数である場合に問題になる可能性があります。これは、多くの場合、ラッパーを使用してプリミティブ関数を呼び出す方が安全であることを意味します。そのため、R 2.7.1 では is.numeric のメソッド ディスパッチが確実に行われるように lapply(ll, function(x) is.numeric(x)) が必要です。正しく。

于 2013-02-18T09:21:58.157 に答える