【问题标题】:Fastest Way to Find the Closest Element to Another Element whose Value is Less in R找到与 R 中值较小的另一个元素最近的元素的最快方法
【发布时间】:2017-08-26 16:09:39
【问题描述】:

我有这个循环将值分配给 branch.from 中的一个元素,该元素表示最接近(小于)其值小于分支中相应元素的值的索引。

for (j in 2:length(branch)) {
  branch.from[j]<-max(which(branch[1:(j-1)]<=branch[j]))
}

branch 有超过 800 万个元素,所以这对我来说花费的时间太长了。有更快的方法吗? 例如,

branch[1:20]<-c(1,54,25,54,22,54,36,54,43,54,40,54,27,54,34,54,26,54,32,54)

以上代码给出,

branch.from[1:20]<-c(1,1,1,3,1,5,5,7,7,9,7,11,5,13,13,15,5,17,17,19)

【问题讨论】:

  • 您能否添加一个向量样本branchbranch.from(不需要与您自己的数据具有相同的大小,但可能保持它们大小的相同比例)。
  • @DominicComtois,希望对您有所帮助。
  • 抱歉,我无法弄清楚其中的逻辑...我通过cbind(branch, closest=branch[branch.from]) 看到了“匹配”的数字,但看不到它与您的描述有何关联。

标签: r


【解决方案1】:

一个 Rcpp 函数

我不确定是否有任何简单的方法来矢量化代码,所以 Rcpp 可能是最好的选择:

library(Rcpp); library(inline)

fun2 <- cppFunction(
    'std::vector<int> branchFrom(NumericVector branch)
{
    std::vector<int> branch_from;
    for(int j = branch.size() - 1; j > 0; j--) {
        int val = -1;
        for(int k = j - 1; k > -1; k--){
            if(branch[j] >= branch[k]){
                val = k;
                break;
            }
        }
        branch_from.push_back(val + 1);
    }
    branch_from.push_back(1);
    std::reverse(branch_from.begin(), branch_from.end());
    return branch_from;
}')

请注意,第二个 for 循环不一定会遍历所有 k,因为一旦找到单个值 x[k] &lt;= x[j],它就会停止。

分析

使用微基准包中的microbenchmark(),其中原始实现封装在base中,我得到以下信息:

Unit: microseconds
 expr     min       lq     mean  median      uq      max neval
 base 124.232 130.3555 152.7990 133.941 141.176 1048.724   100
 fun2   5.105   5.8145   8.0211   7.137   7.766   79.508   100

这表明与最初的实现相比有了显着的加速。

【讨论】:

  • 谢谢。我真的需要学习如何编码。前 200 万个元素使用我的代码需要一天时间;整个 800 万只用了你几秒钟。
猜你喜欢
  • 1970-01-01
  • 2019-07-07
  • 2020-04-29
  • 2011-12-09
  • 1970-01-01
  • 2023-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多