比较具有多个条件的两个大数值向量而不进行循环

时间:2014-06-04 09:58:42

标签: r

我有两个大小为~100K的大向量,其中包含整数数据,例如0,1,2,3 ... 70。 我想逐个元素地将这两个向量与多个条件进行比较,并在条件的第3个向量基础上放置一个值。如果我使用for循环和多个if语句循环执行此操作,则需要大约5个小时才能在良好的电源集群上运行。有没有办法可以加快速度或者在没有循环的情况下实现结果?

感谢。

示例:

A <- c(3,0,1,0,6,1,10,5,1,8,1,4) # 12 elements each
B <- c(1,0,5,1,0,2,2,4,0,1,2,10)

条件:

if(A[i]==1 && B[i]==1)
{
  C[i] <- "Alpha"
}
if(A[i]>=1 || B[i]>=1)
{
   if(A[i]>1 || B[i]>1)
  {
     C[i] <- "Bravo"
  }
}
if(A[i]==0 || B[i]==0)
{
   if(A[i]>=1 || B[i]>=1)
   {
     C[i] <- "Charlie"
   }
}
if(A[i]==0 && B[i]==0)
{
   C[i] <- "Delta"
}

2 个答案:

答案 0 :(得分:2)

我运行了for循环版本,结果与以下内容相符:

A <- c(3,0,1,0,6,1,10,5,1,8,1,4) # 12 elements each
B <- c(1,0,5,1,0,2,2,4,0,1,2,10)

C <- ifelse((A==1 & B==1), "Alpha", 
            ifelse((A==0 | B==0) & (A>=1 | B>=1), "Charlie",
                   ifelse((A>=1 | B>=1) & (A>1 | B>1), "Bravo",               
                          ifelse(A==0 & B==0, "Delta", NA))))

C

##  [1] "Bravo"   "Delta"   "Bravo"   "Charlie" "Charlie" "Bravo"   "Bravo"   "Bravo"   "Charlie" "Bravo"  
## [11] "Bravo"   "Bravo"

这也确实提高了速度:

set.seed(1492)

A <- sample(0:10, 100000, replace=TRUE)
B <- sample(0:10, 100000, replace=TRUE)

system.time(C <- ifelse((A==1 & B==1), "Alpha", 
            ifelse((A==0 | B==0) & (A>=1 | B>=1), "Charlie",
                   ifelse((A>=1 | B>=1) & (A>1 | B>1), "Bravo",               
                          ifelse(A==0 & B==0, "Delta", NA)))))

##  user  system elapsed 
## 0.350   0.004   0.354 

单个&|运算符的原因直接来自R帮助:

  

&安培;和&amp;&amp;表示逻辑AND和|和||表示逻辑OR。较短的形式以与算术运算符大致相同的方式执行元素比较。较长的形式从左到右评估仅检查每个向量的第一个元素。评估仅在确定结果之前进行。较长的形式适用于编程控制流程,通常在if子句中是首选。

答案 1 :(得分:2)

当你一次使用整个向量时,R是最有效的,让底层的fortran / C负责优化。所以你可以尝试类似的东西:

  C <- rep("Alpha",length(A))
  C[(A>=1 | B>=1) & (A>1 | B>1)] <- "Bravo"
  C[(A==0 | B==0) & (A>=1 | B>=1)] <- "Charlie"
  C[A==0 & B==0] <- "Delta"

注意|&||&&的矢量化版本,可以比较元素(帮助位于?'|'