【问题标题】:Speed up nested apply code in R加速 R 中的嵌套应用代码
【发布时间】:2014-05-20 21:24:10
【问题描述】:

我在 R 中有一个包含 2 列的大型数据框(下面有 a 和 b 的样本)。

set.seed(12);n =5;n_a=5;n_b=5
id_lengths = sample(1:n,n_a,replace=T)
a = rep(1:n_a,id_lengths)
b = sample(1:n_b,length(a),replace =T)
data = data.frame(a = a,b = b)

我想为每个“a”在“a”列中获取唯一值的排序向量。该向量应根据“b”列按最大重叠排序。我正在使用下面的代码来实现结果。

get_similar_ids = function(z){
    tmp = sapply(a_list,FUN = function(z1){length(intersect(z1,z))})
    sort(tmp,decreasing=T)
}
a_list = split(data$b,data$a)
lapply(a_list,FUN=get_similar_ids)

结果:

$`1`
1 2 3 4 5
1 1 0 0 0

$`2`
2 1 3 5 4
3 1 1 1 0

$`3`
3 2 4 1 5
3 1 1 0 0

$`4`
3 4 1 2 5
1 1 0 0 0

$`5`
2 5 1 3 4
1 1 0 0 0

问题是实际数据有很大的 n_a (~1700000)、n_b (~250000) 和 n(~15) 导致数据行数超过 1300 万行,对于这么大的代码根本无法复制价值观。 任何想法如何加快这些操作??

【问题讨论】:

  • 您描述了“我想为每个“a”获取“a”列中唯一值的排序向量。您的数据只有一行a == 1,但您的第一个列表元素包含 1 和 2 的条目。这是正确的吗?如果没有,那么您可以进一步简化 James 的解决方案。
  • 是的,1 和 2 都应该在第一个列表元素中有条目,因为 a==1 和 a==2 有 1 个公共 b (b=1)。

标签: r performance loops lapply


【解决方案1】:

您可以通过一些简单的线性代数对原始数据的制表获得所需的输出数据:

(x <- with(data,(table(a,b)>0) %*% (table(b,a)>0)))
   a
a   1 2 3 4 5
  1 1 1 0 0 0
  2 1 3 1 0 1
  3 0 1 3 1 0
  4 0 0 1 1 0
  5 0 1 0 0 1

那么只要按照自己的意愿排序即可:

lapply(unique(data$a), function(y) sort(x[,y],decreasing=TRUE))
[[1]]
1 2 3 4 5 
1 1 0 0 0 

[[2]]
2 1 3 5 4 
3 1 1 1 0 

[[3]]
3 2 4 1 5 
3 1 1 0 0 

[[4]]
3 4 1 2 5 
1 1 0 0 0 

[[5]]
2 5 1 3 4 
1 1 0 0 0 

【讨论】:

  • 感谢您的回答。我已对问题进行了编辑,以使示例数据集更接近我正在使用的真实数据。在实际数据中,“a”列中的唯一值数量约为 170 万,“b”列中为 25 万。由于这个 R 无法制作 1.7M X 1.7M 矩阵,给出错误:“表中的错误(a,b):尝试制作具有 >= 2^31 个元素的表”
  • 您将在输出中包含这么多元素,因此无论以何种方式处理这些数字,您都会遇到问题。仅输出的存储量将是 10-20Tb,具体取决于是否可以使用整数。我怀疑矩阵会很稀疏,因此您可以使用稀疏矩阵实现来提供帮助,但数据的列表表示仍然需要更大的存储空间。
  • 如果结果可能是稀疏的,那么请尝试下面我的 merge 方法,因为它会从一开始就省略空的交叉点。如果不是,您是否真的确定要量化所有条目,或者是否会采用启发式方法来获得前几对 a - 您可以找到最常见的 bs 并将自己限制为 as包含那些,...
【解决方案2】:

您可以通过删除 data 的重复行来加快速度,因为intersect 对集合进行操作,因此不会计算相同 b 的多个实例em> 在 a 中。根据大 n 的含义(更多行、更多不同的 a、更多不同的 b、...?),另一种方法是通过以下方式生成所有重叠:

d2 <- data[!duplicated(data),]
mer <- merge(d2, d2, by="b")
table(paste0(d2$a.x, d2$a.y))

这将为您提供所有非零重叠的 a 坐标。或table(d2$a.x, d2$a.y),然后您可以按行排序。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-14
    • 2013-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多