统计211

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 4316|回复: 2
打印 上一主题 下一主题

马恩驰:R向量化运算

[复制链接]
跳转到指定楼层
1
发表于 2014-8-5 14:33:33 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
一、背景

当今社会,数据量剧增让我们越来越关注计算或算法的效率。“并行和分布式”计算是目前主流的能有效提升计算效率的方法,但学习及实施成本较高。所以,向量化运算对于提升计算效率是个不错的选择。作为并行计算的先驱,向量化运算在提升计算效率的同时,也能一定程度上培养数据分析人员的结构化思维。

向量化计算是一种特殊的并行计算的方式,相比于一般程序在同一时间只执行一个操作的方式,它可以在同一时间执行多次操作,通常是对不同的数据执行同样的一个或一批指令,或者说把指令应用于一个数组/向量(from wikipedia);在R中,向量是R的基本运算对象,当你对一个向量计算时,R会对每个元素进行分别处理,最终结果以向量的形式输出,向量化运算在R中有很广泛的应用场景。

二、应用场景

应用场景很大程度上决定我们知识的储备和工具的选择,总结了一下,向量化运算在R中的应用场景主要有以下三点:

向量的取值与赋值
apply系列函数在数据处理中的应用
矩阵运算
向量的取值与赋值:这部分应用范围较广,针对较大的数据,如果把向量化运算的思维融入抽样当中,也能明显提升抽样效率,向量的赋值最常见的应用是做缺失值的填补,以上两个应用时数据挖掘的基本功,好的模型需要高质量的数据,高质量的数据需要花精力去清洗。

向量化运算最熟悉的莫过于apply系列函数,这部分函数主要包括:apply,lapply,sapply,tapply,aggreate,by,这几个函数比较基础的向量化运算函数。当然也有Hadley Wickham两个包plyr和reshape,能很容易实现以上函数的功能。 矩阵运算的重要程度相比都很清楚,R也一直提倡做矩阵运算,特别是在文本挖掘和图形处理中的稀疏矩阵处理,向量化运算能大幅提升运算的效率;

三、实例介绍

这个部分主要简单介绍一下前面说过的几个向量化运算函数,然后了解一下plyr包(通过Rstudio镜像获取的下载R包数据发现这个包的下载量一直是第一);

1.apply:对矩阵/数组的行或列应用函数


#生成4*4的矩阵
M <- matrix(seq(1,16), 4, 4)
#对行求和
apply(M, 1, sum)
[1] 120 128 136 144
#分别对行和列汇总
apply(M, c(1,2), sum)
     [,1] [,2] [,3] [,4]
[1,]   18   26   34   42
[2,]   20   28   36   44
[3,]   22   30   38   46
[4,]   24   32   40   48

#注:对于矩阵还可以用colMeans, rowMeans, colSums, rowSums做行列运算
2.lapply:对列表应用函数,返回列表

x <- list(a = 1, b = 1:3, c = 10:100)
lapply(x, FUN = sum)
$a
[1] 1
$b
[1] 6
$c
[1] 5005
3.sapply:对列表应用函数,返回向量,这个比较常用,等价于unlist(lapply(…)),用lapply计算,然后把结果变为向量;

x <- list(a = 1, b = 1:3, c = 10:100)
sapply(x, FUN = sum)   
a    b    c   
1    6 5005
unlist(lapply(x,sum))
a    b    c   
1    6 5005   
4.tapply:对各因子应用函数(也就是分组计算),这个也常用;

x <- 1:20
y <- factor(rep(letters[1:5], each = 4))
tapply(x, y, sum)  
a  b  c  d  e  
10 26 42 58 74
5.aggreate:split-apply-combine,拆分成子集,分别计算合并结果输出;

testDF <- data.frame(v1 = c(1,3,5,7,8,3,5,NA,4,5,7,9),
                     v2 = c(11,33,55,77,88,33,55,NA,44,55,77,99) )
by1 <- c("red", "blue", 1, 2, NA, "big", 1, 2, "red", 1, NA, 12)
by2 <- c("wet", "dry", 99, 95, NA, "damp", 95, 99, "red", 99, NA, NA)
aggregate(x = testDF, by = list(by1, by2), FUN = "mean")
Group.1 Group.2 v1 v2
1       1      95  5 55
2       2      95  7 77
3       1      99  5 55
4       2      99 NA NA
5     big    damp  3 33
6    blue     dry  3 33
7     red     red  4 44
8     red     wet  1 11
更简洁易用的plyr包

以上几个函数在实际应用中比较容易混淆,针对输入对象与输出对象应该应用什么函数,见下图:

1

坦白说,以上函数不太容易记住,再来看一下plyr的函数,取输入输出对象的第一个字母+ply;通俗易懂;

2

以常用的ddply函数为例做演示:


#以mtcars数据为例
str(mtcars)
'data.frame':        32 obs. of  11 variables:
$ mpg : num  21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
$ cyl : num  6 6 4 6 8 6 8 4 4 6 ...
$ disp: num  160 160 108 258 360 ...
$ hp  : num  110 110 93 110 175 105 245 62 95 123 ...
$ drat: num  3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
$ wt  : num  2.62 2.88 2.32 3.21 3.44 ...
$ qsec: num  16.5 17 18.6 19.4 17 ...
$ vs  : num  0 0 1 1 0 1 0 1 1 1 ...
$ am  : num  1 1 1 0 0 0 0 0 0 0 ...
$ gear: num  4 4 4 3 3 3 3 4 4 4 ...
$ carb: num  4 4 1 1 2 1 4 2 2 4 ...
#计算每个气缸水平下,mpg的均值和标准差
ddply(mtcars,"cyl",summarise,mean.mpg=mean(mpg),sd.mpg=sd(mpg))
cyl mean.mpg   sd.mpg
1   4 26.66364 4.509828
2   6 19.74286 1.453567
3   8 15.10000 2.560048
注:数据量比较大时,plyr包的运算效率不理想,曾经用ddply处理一个347万*9的数据框,半个小时没出结果,后来我就放弃了;

plyr上手比较快,结合reshape,掌握部分函数,基本就可以远离EXCEL透视表了,想接着往下走也很容易。

来源:http://www.itongji.cn/article/0H524632013.html

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 转播转播 分享分享 分享淘帖 支持支持 反对反对
2
发表于 2014-8-7 21:44:11 | 只看该作者
apply系列的函数功能强大,但实质上也是for循环,在R里面for循环运行比较慢,若比较多层会耗费比较多的时间,要注意使用~
3
 楼主| 发表于 2014-8-8 12:39:06 | 只看该作者
那就是用apply比用for要好~~
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则


免责声明|关于我们|小黑屋|联系我们|赞助我们|统计211 ( 闽ICP备09019626号  

GMT+8, 2025-4-4 21:38 , Processed in 0.090818 second(s), 23 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表