亲爱的StackOverflowers :),我正在尝试从使用先前列作为输入的表达式计算我的数据框中的新列。我编写了一个函数,但是在650,000行的数据帧中需要花费数小时,而完整的数据集将有330万行!
我想知道如何优化我的代码,或者我是否应该在我的部门寻找更强大的PC。 这是一个例子:
testdf99<- data.frame('V1'= c(1:10), 'V2'= c(2,3,4,5,3,2,2,3,8,8))
我的目的是创建一个Var3列:
my_calculator<- function(input_table){
table0<- input_table
colnames(table0)<- c('Coordinate', 'Var1')
table0$Var2<- table0$Coordinate+table0$Var1-1
table0$Var3<- -99 # as sanity check
#Now let's calculate Var3 at each position
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)}
return(table0)}
创建Var2似乎是即时的,但是当我将Var3插入到函数中时,它会持续数小时(〜650,000行)。
我将不胜感激任何有关更好的代码的建议,这些代码可以明智地加速计算。
答案 0 :(得分:1)
这是我尝试将您的函数转换为应用样式循环的尝试。
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
现在有一些时间:
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
编辑:你总是可以包含一些Rcpp代码,这个代码包含了很棒的c ++ Armadillo库。
#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)
请注意,这只会创建一个列矩阵,即var3。