【问题标题】:Merge a large list of logical vectors合并大量逻辑向量
【发布时间】:2015-08-27 16:33:19
【问题描述】:

我有一个很大的TRUE/FALSE 逻辑向量列表(144 个列表元素,每个约 2300 万个元素长)。我想使用any 合并它们以生成一个逻辑向量。如果每个列表元素的任何第一个元素是TRUE,则返回TRUE,以此类推,以获取向量的长度。这是一个例子:

#  Some data
set.seed(1)
ll <- replicate(3,sample(c(TRUE,FALSE),5,TRUE),simplify=F)

#[[1]]
#[1]  TRUE  TRUE FALSE FALSE  TRUE

#[[2]]
#[1] FALSE FALSE FALSE FALSE  TRUE

#[[3]]
#[1]  TRUE  TRUE FALSE  TRUE FALSE

#  What I want (and one way of doing it)...
apply( do.call(cbind,ll) , 1 , any )
#  [1]  TRUE  TRUE FALSE  TRUE  TRUE

等等,你已经在该代码中发布了解决方案,为什么还要问这个问题?

我的真实数据中有 144 个向量,每个向量的长度为 23,721,703。尝试上述操作会引发错误,例如:

# *** caught segfault ***
#address 0x18, cause 'memory not mapped'

OR

#Error in aperm.default(X, c(s.call, s.ans)) : 
#  long vectors not supported yet: memory.c:1648

我在 Ubuntu 64 位和 112Gb RAM 上运行 R 3.0.2。

【问题讨论】:

  • 不确定这是否有帮助,Reduce('|', ll)
  • 无需一次绑定所有 144 个向量。将其分解为多个通道。比较前 10 个。然后是下一个。或者 cpu 可以处理的任何负载。 any(cbind(first10vectors)) 将输出一个可以与any(cbind(newvector, next10vectors)) 进行比较的逻辑向量。
  • @akrun 谢谢你们俩。这些都是很好的建议。我首先尝试Reduce 方法,如果它有效,我会告诉你 - 需要一段时间才能读取所有数据(通过云虚拟机中较慢的网络连接)。
  • @SimonO'Hanlon 基于 1e5 大小的列表元素,Reducesystem.time 更快。但是,我没有使用更大的数据集。
  • @akrun 速度不一定是我主要关心的问题——我实际上更希望操作完成(尽管在合理的时间范围内)。我正在使用data.table,所以我真正的电话是dt[ , lapply( .SD , function(x) x == "?" ) , .SDcols = 4:ncol(dt) ][ , Reduce('|',.SD) ],它在测试用例中效果很好。让我们看看....

标签: r list merge bigdata


【解决方案1】:

你可以使用Reduce

  Reduce('|', ll)

基准测试

set.seed(1)
ll <- replicate(144, sample(c(TRUE, FALSE), 1e5,
       replace=TRUE), simplify=FALSE)
system.time(apply(do.call(cbind, ll), 1, any))
# user  system elapsed 
# 0.575   0.022   0.598 

system.time(Reduce(`|`, ll))
# user  system elapsed 
# 0.287   0.008   0.295 

【讨论】:

  • rowSums(do.call(cbind, ll))&gt;0apply( ) 代码好很多,但仍然比Reduce( ) 慢...
猜你喜欢
  • 1970-01-01
  • 2022-12-12
  • 1970-01-01
  • 2013-10-15
  • 1970-01-01
  • 2021-10-01
  • 2021-06-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多