YAVL:R中的另一个矢量化循环

时间:2014-06-11 19:11:36

标签: r

我只是在处理使用R对代码进行矢量化(链接到有用的示例会有所帮助),我正在尝试找到一种更快的方法来处理这个循环。 a,b,c都有一堆数字,我试图找到所有3列中出现的任何特定数字。循环工作,但速度超慢:

for(i in 1:length(a)){
  if(any(a[i]==b))
    if(any(a[i]==c))
      print(a[i])
}

是否有适用于此功能的应用功能?

4 个答案:

答案 0 :(得分:4)

也许这个?

x <- 1:5
y <- 4:10
z <- 4:8
> Reduce(intersect,list(x,y,z))
[1] 4 5

答案 1 :(得分:3)

我看到你接受了@joran解决方案,但它确实是隐藏的循环。这是一个&#34;矢量化&#34;溶液:

> x <- 1:5
> y <- 4:10
> z <- 4:8
> x[ (x %in% y) & (x %in% z) ]
[1] 4 5

答案 2 :(得分:2)

您还可以计算每次出现的总次数(假设每次都没有重复;如果是,请先在它们上运行unique。此代码也会返回所需的数字作为字符;可以转换根据需要回来。

x <- 1:5; y <- 4:10; z <- 4:8
foo <- table(c(x,y,z))
names(foo)[foo==3]
## [1] "4" "5"

答案 3 :(得分:2)

您还可以在for中使用for loop来改善intersect(基本上是在Reduce中使用它)

intersect.list <- function(list) {  ## code from stabperf package
  if (is.null(list)) return(NA)
  # Handle empty list
  if (length(list) < 1) return(NA)
  # Start with first element of list
  int <- list[[1]]
  for (v in list[-1]) { int <- intersect(int, v) }
  return(int)
} 

intersect.list(list(x,y,z))
4 5 

基准测试:

library(microbenchmark)
set.seed(1)
N <- 1e6
x <- sample(1:100,N,rep=T)
y <- sample(1:100,N,rep=T)
z <- sample(1:100,N,rep=T)

vectorized <- function()x[ (x %in% y) & (x %in% z) ]

 microbenchmark(intersect.list(list(x,y,z)),
+                vectorized(),
+                Reduce(intersect,list(x,y,z)),times=10)
Unit: milliseconds
                             expr      min        lq    median        uq      max neval
    intersect.list(list(x, y, z))  73.2862  75.14838  76.77792  85.54216 121.8442    10
                     vectorized() 131.9560 132.40266 134.47248 139.93902 172.7829    10
 Reduce(intersect, list(x, y, z))  88.4308  90.06320  92.72929 128.05930 133.2982    10

正如您所看到的那样,如果稍微快一些,那么Reduce和矢量化解决方案。