首页 > 解决方案 > 应用优化

问题描述

我有计算数据框/矩阵的一致性值的现有代码。它基本上是所有值与总行数相同的行数。

...
concordance<-new[complete.cases(new),] #removes rows with NAs
TF<-apply(concordance, 1, function(x) if(length(unique(x))>1) F else T)
#outputs vector of T/F if it is concordant
numF<-table(TF)["TRUE"]#gets number of trues
concValue<-numF/NROW(TF) #true/total
...

以上是我现在所拥有的。它运行正常,但我想知道是否有任何方法可以让它更快。

编辑:对象的尺寸是可变的,但列数通常为 2-6,通常有 1,000,000+ 行。这是我正在开发的包的一部分,因此输入数据是可变的。

标签: roptimizationapply

解决方案


因为行数远大于列数,所以在列上循环而不是删除行是有意义的,在此过程中存在多个不同的值:

propIdentical <- function(Mat){
    nrowInit <- nrow(Mat)  

    for(i in 1:(ncol(Mat) - 1)){
       if(!nrow(Mat)) break #stop if the matrix has no rows
       else{
            #check which elements of column i and column i+1 are equal:
            equals <- Mat[,i] == Mat[, i+1] 

            # remove all other rows from the matrix
            Mat <- Mat[equals,,drop = F]
       }
    }

    return(nrow(Mat)/nrowInit)
}

一些测试:

set.seed(1)

# normal case
dat <- matrix(sample(1:10, rep = T, size = 3*10^6), nrow = 10^6)
system.time(prI <- propIdentical(dat)) ; prI

 user  system elapsed 
 0.053   0.017   0.070 
[1] 0.009898

# normal case on my pc for comparison:
system.time(app <- mean(apply(dat, 1, function(x) length(unique(x))) == 1L)); app
   user  system elapsed 
 12.176   0.036  12.231 
[1] 0.009898

# worst case
dat <- matrix(1L, nrow = 10^6, ncol = 6)
> system.time(prI <- propIdentical(dat)) ; prI
   user  system elapsed 
  0.302   0.044   0.348 
[1] 1
# worst case on my pc for comparison
system.time(mean(apply(dat, 1, function(x) length(unique(x))) == 1L))
   user  system elapsed 
 12.562   0.001  12.578

# testing drop = F and if(!nrow(Mat)) break
dat <- matrix(1:2, ncol = 2)
> system.time(prI <- propIdentical(dat)) ; prI
   user  system elapsed 
      0       0       0 
[1] 0

注意:如果您在 a 上运行它,请data.frame确保先将其转换为矩阵。


推荐阅读