说到R,人们除了赞美它漂亮简洁的做图功能外,就是抱怨它的运行速度问题。做为常规使用,好比数据整理分析,统计计算或者做图等,或许没有感受到它的运行速度有问题。可是若是数据量很大,像基因组数据,那么运行起来就尤为慢了。特别是对于循环语句,犹如老牛拉破车,因此在数据量很大的状况下,尽可能不要在R中使用循环语句。html
那么循环语句在R中会慢到什么地步?咱们经过R语言和C语言的比较就能看出一些端倪。编程
咱们假设有这么两个数据框,以下图。咱们要判断每个pos中的数据(4,15,19,27)是否落在第一个数据框的数据区间内(2-5,7-11,17-20,23-28,32-39)。这样咱们就会用到两个嵌套for循环,对第二个数据框中的每个数,依次比对第一个数据框中的每个数据段。app
首先咱们使用随机数生成这么两个模拟数据框编程语言
set.seed(111)
creat_test
x
x
start = numeric()
end = numeric()
for (i in seq(1,length(x),2)){
start
end
}
test_df
return(test_df)
}
# create first data frame, using length = 7,000,000, segments = 20,000
test_data
# create second data frame, sequence data
sequence
sequence$x
自此,咱们有了两个测试数据框,第一个test_data里面有20万条观测,第二个sequence里面有400个观测,那么咱们首先经过R中的for循环来判断这400个观测时候落在来第一个数据框中数据段内。ide
# using R loop to see if sequence in test_data range
R_time
num_in
for (i in 1:nrow(sequence)){
for (j in 1:nrow(test_data)){
if (sequence[i,1] > test_data[j,1] & sequence[i,1] < test_data[j,2]){
num_in
break
}
}
}
print(num_in)
}
system.time(R_time(sequence,test_data))
这段代码中两个for循环,大概运行来:函数
下面咱们看一看在C语言中完成这段代码须要多长时间。本人并不了解C语言,可是Rcpp包提供了在R中写C代码的可能,因此使用Rcpp完成上述功能以下:oop
# using Rcpp
library(Rcpp)
cppFunction('
int Rcpp_time(DataFrame sequence, DataFrame test_data){
IntegerVector start=test_data["start"];
IntegerVector end=test_data["end"];
IntegerVector pos=sequence["x"];
int seq_size=sequence.nrow();
int test_size=test_data.nrow();
int num_in=0;
for(int i=0; i<=seq_size; i++){
for(int j=0; j<=test_size; j++){
if(pos[i]>start[j] && pos[i]
num_in++;
break;
}
}
}
return num_in;
}
')
system.time(Rcpp_time(sequence,test_data))
而这段代码的运行时间仅仅为:测试
能够看出,一样的一段代码,获得相同的结果,在R中运行的时间是在C中运行时间的数万倍!什么概念:code
在R中你要等1个多小时,在C中你在1秒内就完成!orm
固然这也很好理解,毕竟相对于C来说,R属于高级编程语言,并且是解释型语言,没有C的编译过程,因此R会针对每个for循环一一执行,这也下降了速度。
那么问题来了,应该怎样提升R的运行速度呢?
一、避免使用for循环,尤为是数据量特别大的时候;
二、避免数据的复制,使用%>%之类的管道操做;
三、使用一些更快的R包处理数据,好比data.table;
四、使用apply、lapply等之类的函数代替for;
五、使用Rcpp编写C语言函数;
六、使用多核并行计算(能够经过lapply来实现);
能够参考http://adv-r.had.co.nz/Performance.html