Pau*_*ray 12 r lapply data.table
我在列表中有一堆data.tables.我想应用于unique()我的列表中的每个data.table,但这样做会破坏我的所有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)
Run Code Online (Sandbox Code Playgroud)
在这里,blah仍然有一把钥匙,世界上的一切都是正确的:
key(blah)
# [1] "a"
Run Code Online (Sandbox Code Playgroud)
但是,如果我将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
Run Code Online (Sandbox Code Playgroud)
这可能与我有关,并没有真正理解"通过引用"分配键意味着什么,因为我有其他问题,密钥消失了.
所以:
编辑:
对于它的价值,可怕的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"
Run Code Online (Sandbox Code Playgroud)
但这是R,for循环是邪恶的.
有趣的是,请注意这两种不同结果之间的差异
lapply(dt.list, unique)
lapply(dt.list, function(x) unique(x))
Run Code Online (Sandbox Code Playgroud)
如果您使用后者,结果如您所料.
看似意外的行为是由于第一个lapply语句在第二个语句调用时调用unique.data.frame(即从{base})unique.data.table
好问题.事实证明它已记录在案?lapply(参见注释部分):
由于历史原因,lapply创建的调用未被评估,并且代码已经编写(例如bquote)依赖于此.这意味着记录的调用始终为FUN(X [[0L]],...)形式,0L由当前整数索引替换.这通常不是问题,但是如果FUN使用sys.call或match.call,或者它是一个使用该调用的原始函数.这意味着使用包装器调用原始函数通常更安全,因此例如在R 2.7.1中需要lapply(ll,function(x)is.numeric(x))以确保发生is.numeric的方法调度正确.