【问题标题】:Parallel 'or' operation on many logical vectors许多逻辑向量上的并行“或”运算
【发布时间】:2016-10-04 06:53:00
【问题描述】:

在 R 中,我有许多逻辑向量,或不同的数量(即有时 1,有时 n 向量),它们保证都是相同的长度,我需要生成一个向量与输入向量的长度相同,如果相同元素索引处的任何向量为TRUE,则每个元素为TRUE,否则为FALSE

我想知道是否有内置操作或更简单的方法来实现我想要的。以下是我目前拥有的 3 个向量。

set.seed(1) #For reproducability
o = c(T,F)
l = 10
A = sample(o,l,replace=T)
B = sample(o,l,replace=T)
C = sample(o,l,replace=T)
fun = function(...) apply(do.call(cbind,args = list(...)),1,any)
fun(A,B,C) ##Produces Desired Result

【问题讨论】:

标签: r parallel-processing logical-operators


【解决方案1】:

这里是上面列出的各种方法的一些基准,使用@Roland 建议的更大向量。

set.seed(1) #For reproducability
o = c(T,F)
l = 1000000
A = sample(o,l,replace=T)
B = sample(o,l,replace=T)
C = sample(o,l,replace=T)

library(microbenchmark)
f.0 = function() apply(do.call(cbind,args = list(A,B,C)),1,any)
f.a = function() Reduce(`|`, list(A, B, C))
f.b = function() rowSums(cbind(A,B,C))!=0
f.c = function() !!(A+B+C)
f.d = function() !!(Reduce('+',lapply(LETTERS[1:3],get)))
f.e = function() Reduce('|', mget(LETTERS[1:3]))
f.f = function() matrixStats::rowAnys(cbind(A, B, C))
microbenchmark(f.0,f.a,f.b,f.c,f.d,f.e,f.f,times=10000)

在我的带有 I7 处理器的 macbook air 上产生以下结果。

Unit: nanoseconds
 expr min lq     mean median  uq   max neval
  f.0  39 57 118.4767     78 123 23685 10000
  f.a  43 61 119.5952     85 130 63523 10000
  f.b  38 53 100.5252     77 120 27199 10000
  f.c  39 55 100.9784     77 121 17656 10000
  f.d  37 52 111.5138     75 118 78505 10000
  f.e  39 57 113.1461     80 125 16111 10000
  f.f  35 52 105.9245     74 117 19995 10000

所以它们看起来都非常接近,我最初的方法不是最慢的,但也不是最快的......

【讨论】:

  • 我可以建议使用整洁的microbenchmark 包吗?
  • 好的。很公平。裤子不同的图片。
  • 当您得到多个答案时进行基准测试是个好主意。
  • @Roland,干杯,我已经修改了代码来测试长度为 1e6 的向量
【解决方案2】:

我们可以使用Reduce|

Reduce(`|`, list(A, B, C))

rowSums

rowSums(cbind(A,B,C))!=0

如果只有 3 个向量,那么紧凑的选项是

!!(A+B+C)

【讨论】:

  • 我不能保证向量的数量,数量只有在运行时才知道,所以前2个可以,最后一个不行。
  • @NicholasHamilton 感谢您的回复。我会把它留给其他有 3 或 4 个向量的人。
  • 这是另一个选项:!!(Reduce('+',lapply(LETTERS[1:3],get)))
  • @NicholasHamilton 可以使用get,而不是Reduce('|', mget(LETTERS[1:3]))
  • 有人想对所有这些变化进行基准测试吗?
猜你喜欢
  • 1970-01-01
  • 2012-06-30
  • 2011-08-25
  • 1970-01-01
  • 1970-01-01
  • 2021-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多