如何将一个向量中的所有值与另一个向量中的所有值进行比较? (在最短的时间内)

时间:2017-03-29 01:17:10

标签: r

我有以下代码:

list1 <- c(5, 6, 8, 10, 15, 26, 75) 
list2 <- c(3, 6, 8, 10, 100, 42)

total <- length(list1)*length(list2)
  for(x in 1:length(list1)) {
    for(y in 1:length(list2)) {
      print(total - (x*y))
      if(list1[x]>list2[y]) {
        l1Bigger <- l1Bigger + 1
      } else if(list1[x]<list2[y]) {
        l2Bigger <- l2Bigger + 1
      } else {
        tie <- tie + 1
      }
    }
  }
  percents <- c(l1Bigger/total, l2Bigger/total, tie/total)
  return(percents)

基本上,我希望我的代码要做的是遍历list1和list2并比较这些值以确定list1中的值大于列表2中的值的频率。我当前的方法需要花费很多时间,是有没有办法减少这个过程花费的时间?

谢谢!

2 个答案:

答案 0 :(得分:2)

expand.grid是做这种事情的自然方式:

> x <- c(2,4,5,1,3)
> y <- c(1,6,2,3)
> g <- expand.grid(x,y)
> x.bigger <- sum(g$Var1 > g$Var2)
> y.bigger <- sum(g$Var1 < g$Var2)
> ties <- sum(g$Var1 == g$Var2)
> x.bigger
[1] 9
> y.bigger <- sum(g$Var1 < g$Var2)
> ties
[1] 3

当然,ties可以通过其他两个值的简单算法来计算,但我想展示如何直接获得所有三个数字。

答案 1 :(得分:2)

你可以将你所拥有的内容转换为Rcpp,这可以加快长向量的过程

library(Rcpp)

set.seed(1)
v1 <- rnorm(10000)
v2 <- rnorm(10000)

cppFunction('NumericVector compareVectors(NumericVector v1, NumericVector v2){

            NumericVector out(3);

            for(int i = 0; i < v1.size(); i++){
               for(int j = 0; j < v2.size(); j++){
                  if(v1[i] == v2[j]){
                     out[0]++;
                  }else if(v1[i] < v2[j]){
                     out[1]++;
                  }else{
                     out[2]++;
                  }
               }
            }
            return out;
        }')

compareVectors(v1, v2)
[1]          0 5008309906 4991690094

在基准测试时显示出有利的结果

library(microbenchmark)

set.seed(1)
v1 <- rnorm(1000)
v2 <- rnorm(1000)

microbenchmark(

    rcpp = {
        compareVectors(v1, v2)
    },
    exg = {
        g <- expand.grid(v1, v2)
        x.bigger <- sum(g$Var1 > g$Var2)
        y.bigge <- sum(g$Var1 < g$Var2)
    }
)

# Unit: milliseconds
# expr       min        lq      mean    median        uq        max neval
# rcpp  5.600956  5.788145  6.036816  5.927468  6.183143   8.385282   100
#  exg 28.529272 35.246216 41.328205 36.000421 37.653801 540.850561   100