楼主: cheetahfly
2674 3

[学习分享] R语言中C++、向量化、和data.table的效率比较 [推广有奖]

  • 2关注
  • 72粉丝

版主

已卖:1份资源

院士

11%

还不是VIP/贵宾

-

威望
0
论坛币
63894 个
通用积分
1679.3337
学术水平
489 点
热心指数
598 点
信用等级
336 点
经验
127401 点
帖子
2098
精华
1
在线时间
3983 小时
注册时间
2010-10-27
最后登录
2025-12-27

楼主
cheetahfly 在职认证  发表于 2016-3-23 22:52:43 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币
我们经常听到一些人谈论R语言的效率问题,又经常听到另一些人评论说这种比较是建筑在“naive”的R语言编程方法上的。如果R语言发挥到极致(仅限于我的能力范围之内),到底能优化到什么程度,这是我在本文希望讨论的问题。

在此之前,再次感谢Iris2126同学,是他的《【R】提升R代码运算效率的11个实用方法》让我得以展开今天的讨论,现在我还经常看会该篇文章,每每都有些收获。

今天我们延续该文的讨论,但比较的是三种最有效率的方法:C++(Rcpp)、最简向量化、和data.table格式,这三种上面文章中都有提到过,但是都不是最优化的,我根据英文原帖的跟帖高手中一些思路照搬过来了(代码非原创,荣誉归于这两位外国高手)。

1、问题的提出,假设有这么一个data.frame:
  1. df <- data.frame (col1 = runif (12^6, 0, 2),
  2.                          col2 = rnorm (12^6, 0, 2),
  3.                          col3 = rpois (12^6, 3),
  4.                          col4 = rchisq (12^6, 2))
复制代码
然后,判断该数据框(df)的每一行的总和是否大于4,如果该条件满足,则对应的新变量数值为’greater_than_4’,否则赋值为’lesser_than_4’。就是这么个简单的问题。

2、a)Rcpp包加载C++函数:(原帖中的C++代码无法运行,且判断语句不知所云,很可能有错漏,我恶补了Rcpp的知识后稍微改动过,可能是比较低效率的代码,请大神指正)
  1. // myfunc.cpp
  2. #include <Rcpp.h>
  3. using namespace Rcpp;

  4. //[[Rcpp::export]]
  5. CharacterVector myFunc(DataFrame x) {
  6.         NumericVector a = x["col1"];
  7.         NumericVector b = x["col2"];
  8.         NumericVector c = x["col3"];
  9.         NumericVector d = x["col4"];
  10.         int nrow = a.size();
  11.         CharacterVector out(nrow);
  12.         for (int i = 0; i < nrow; i++) {
  13.                 if (a[i] + b[i] + c[i] + d[i] > 4) {
  14.                         out[i] = "greater_than_4";
  15.                 } else {
  16.                         out[i] = "lesser_than_4";
  17.                 }
  18.         }
  19.         return out;
  20. }

  21. library(Rcpp)
  22. sourceCpp("myfunc.cpp")
复制代码

b)将向量化做到极致:
  1. myFunR <- function(df) {
  2. c("greater_than_4", "lesser_than_4")[1L + (df[[1]] + df[[2]]  + df[[3]] + df[[4]] <= 4)]
  3. }
复制代码

c)用大名鼎鼎的data.table数据结构(返回的是增加了一列的data.table,而非上两种方式中的向量)
  1. myFundt <- function(df) {
  2.     setDT(df)
  3.     df[, output := "greater_than_4"]
  4.     df[(col1 + col2 + col3 + col4) <= 4, output :="lesser_than_4"]
  5. }
复制代码

3、OK,万事俱备,开始测试:
  1. library(microbenchmark)
  2. library(data.table)
  3. dt <- copy(df) # data.table会改变外部环境,所以要单独拷贝一份出来。
  4. microbenchmark(myFunc(df), myFunR(df), myFundt(dt), times = 30)
复制代码

4、结果。在揭晓之前,我们来猜猜谁最快?C++?

结果.PNG

当然,反正都很快就是了,不过,强中自有强中手,想不到极致向量化的方法比C++更快,而data.table又比极致向量化更快。

具体耗时可能因电脑不同而异,我在两台32位的老电脑上测试过,均是相同的快慢顺序。

5、结论——R语言的潜力我们还根本没有挖掘彻底!静下心来,好好学习吧。

二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:Table ABLE Data tab R语言 语言编程 naive 文章 建筑 能力

已有 1 人评分论坛币 学术水平 信用等级 收起 理由
万人往LVR + 5 + 3 + 3 精彩帖子

总评分: 论坛币 + 5  学术水平 + 3  信用等级 + 3   查看全部评分

沙发
soccy 发表于 2016-3-23 23:15:57
机制向量那个版本根本就是天书。代码写成这样自己过一会都会忘了干嘛了。

藤椅
yangming98 发表于 2016-3-25 22:57:45 来自手机
cheetahfly 发表于 2016-3-23 22:52
我们经常听到一些人谈论R语言的效率问题,又经常听到另一些人评论说这种比较是建筑在“naive”的R语言编程方 ...
学习了

板凳
黑白纯 发表于 2020-5-4 22:46:05
感谢,虽然关于C++的内容丝毫看不懂,但是data.table的运行速度是最快的这一结论对于我这种菜鸟的帮助已经极大了。感谢版主的测试和分享

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注cda
拉您进交流群
GMT+8, 2025-12-30 11:37