对多个逻辑向量进行并行 'or' 操作
Parallel 'or' operation on many logical vectors
在 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
我们可以使用 Reduce
和 |
Reduce(`|`, list(A, B, C))
或 rowSums
rowSums(cbind(A,B,C))!=0
如果只有 3 个向量,一个紧凑的选项是
!!(A+B+C)
下面是上面列出的各种方法的一些基准,使用 @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
所以它们看起来都非常接近,我最初的方法不是最慢的,但也不是最快的...
在 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
我们可以使用 Reduce
和 |
Reduce(`|`, list(A, B, C))
或 rowSums
rowSums(cbind(A,B,C))!=0
如果只有 3 个向量,一个紧凑的选项是
!!(A+B+C)
下面是上面列出的各种方法的一些基准,使用 @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
所以它们看起来都非常接近,我最初的方法不是最慢的,但也不是最快的...