概述
给一个大的(nrows> 5,000,000+)数据框 A ,包含字符串行名和不相交集列表(n = 20,000+), B ,其中每一组都包含来自 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-esque或优雅,这是非常慢的(几个小时)。
如何以快速有效的方式生成所需的结果?
答案 0 :(得分: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
会派上用场。