优化在大型数据帧中从espression创建列

优化在大型数据帧中从espression创建列,r,dataframe,R,Dataframe,亲爱的StackOverflowers:),我正在尝试从使用以前列作为输入的表达式计算数据帧中的新列。我已经编写了一个函数,但是在一个650000行的数据帧中需要花费数小时,而整个数据集将有330万行 我想知道如何优化我的代码,或者我是否应该在我的部门寻找一些更强大的PC。 下面是一个例子: testdf99<- data.frame('V1'= c(1:10), 'V2'= c(2,3,4,5,3,2,2,3,8,8)) testdf99下面是我将函数转换为apply样式循环的尝试 f

亲爱的StackOverflowers:),我正在尝试从使用以前列作为输入的表达式计算数据帧中的新列。我已经编写了一个函数,但是在一个650000行的数据帧中需要花费数小时,而整个数据集将有330万行

我想知道如何优化我的代码,或者我是否应该在我的部门寻找一些更强大的PC。 下面是一个例子:

testdf99<- data.frame('V1'= c(1:10), 'V2'= c(2,3,4,5,3,2,2,3,8,8))

testdf99下面是我将函数转换为apply样式循环的尝试

f1 <- function(table0){
  for (i in 1:nrow(table0)){
    #position of i
    i_POS<- table0[i,'Coordinate']
    # Var1 covering i_POS
    table1<- table0[table0$Coordinate<= i_POS & table0$Var2>= i_POS,]
    table0[i, 'Var3']<- max(table1$Var1)
  }
  table0
}

f2 <- function(table0){
    mutate(table0, lapply(1:10, function(i){ 
      max(table0[table0$Coordinate<= i & table0$Var2>= i,]$Var1)
    }))
}


all.equal(f1(table0), f2(table0))
[1] TRUE
<>编辑:你可以总是包含一些RCPP代码,这是一个带有C++ C++的ARMADILO库。
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]

using namespace Rcpp;
using namespace arma;

// [[Rcpp::export]]
vec f3(arma::mat table0) {

  int t0_rows = table0.n_rows;
  vec coord = table0.col(0);
  vec var1 = table0.col(1);
  vec var2 = table0.col(2);
  vec var3 = zeros<vec>(t0_rows);

  for(int i = 0; i < t0_rows; i++){
    var3(i) = max(var1(find((coord <= coord[i]) &&
      var2  >= coord[i])));
  }
  return var3;
}

table0_v3 <- f3(table0)
#包括
//[[Rcpp::depends(RcppArmadillo)]]
使用名称空间Rcpp;
使用arma;
//[[Rcpp::导出]]
vec f3(arma::mat表0){
int t0_行=表0.n_行;
向量坐标=表0.col(0);
vec var1=表0.col(1);
vec var2=表0.col(2);
vec var3=零(t0_行);
对于(int i=0;itable0_v3亲爱的Shayaa,感谢您的善意帮助,并向我介绍了神奇的dplyr包!它看起来很神奇,我正在阅读有关它的内容。我已经在我的主函数中实现了脚本,并测试了结果。现在我将在650k行数据集上运行它,看看会发生什么。从您的测试来看,它应该非常快!与此同时,有一点我不明白:为什么函数末尾没有“return”呢?我已经测试过了,如果我包括return(表0),结果基本上忽略了mutate函数。我不知道我在这里缺少了什么:(??因为对mutate的调用是函数返回值。默认情况下,如果未将函数体中的最后一个调用赋给变量,函数将返回函数体中的最后一个调用。如果希望有特定的返回值,可以将此mutate调用保存到table0,然后返回table0。谢谢,这很有意义。我运行新函数已有一年了现在已经过去了1小时20分钟。祈祷好运,很快就会结束:)哇,这是一个很长的时间。我将用RcppArmadillo版本编辑我的答案。如果这对您有帮助,欢迎您单击解决方案旁边的复选框。是的,但我没有您的真实数据。这有助于构建一个示例,它可以最小限度地重建您的数据。
library(microbenchmark)
microbenchmark(f1(table0),f2(table0))

Unit: microseconds
       expr      min        lq      mean    median       uq      max neval
 f1(table0) 1266.691 1317.8750 1693.9076 1602.0810 1872.075 2931.152   100
 f2(table0)   13.892   18.1005   33.1414   26.4715   42.242  123.525   100
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]

using namespace Rcpp;
using namespace arma;

// [[Rcpp::export]]
vec f3(arma::mat table0) {

  int t0_rows = table0.n_rows;
  vec coord = table0.col(0);
  vec var1 = table0.col(1);
  vec var2 = table0.col(2);
  vec var3 = zeros<vec>(t0_rows);

  for(int i = 0; i < t0_rows; i++){
    var3(i) = max(var1(find((coord <= coord[i]) &&
      var2  >= coord[i])));
  }
  return var3;
}

table0_v3 <- f3(table0)