How to avoid a loop to calculate competition index

前端 未结 2 480
故里飘歌
故里飘歌 2020-12-20 08:56

I\'ve to calculate so called competition index for a couple of the experiments. I have known position of the object and its size. I\'d like to calculate the sum of the sizes

2条回答
  •  时光取名叫无心
    2020-12-20 09:21

    Loops like this are a perfect candidate for speeding up with Rcpp. The logic translates across unchanged:

    library(Rcpp)
    
    cppFunction('
    List
    computeIndex(const NumericVector x,
                 const NumericVector y, 
                 const NumericVector di,
                 const CharacterVector ex)
    {
        int n = x.size();
        NumericVector comp1(n), dist(n);
    
        for(int i = 0; i < n; ++i)
        {
            for(int j = 0; j < n; ++j)
            {
                double dx = x[j] - x[i], dy = y[j] - y[i];
                double d = std::sqrt(dx*dx + dy*dy);
    
                if((d < 2) && (ex[i] == ex[j]))
                {
                    comp1[i] += di[j];
                    dist[i] +=  d;
                }
            }
        }
    
        return List::create(Named("comp1") = comp1,
                            Named("dist") = dist);
    }
    ')
    
    res <- data.frame(computeIndex(df$x, df$y, df$di, df$exp))
    

    Not only is this faster than the equivalent R-only code, but it avoids having to allocate any O(N^2) objects. You can also combine this with dplyr to avoid needless comparisons between rows with different exp values:

    df %>%
        group_by(exp) %>%
        do({
            res <- computeIndex(.$x, .$y, .$di, .$exp)
            data.frame(., res)
        })
    

提交回复
热议问题