内容简介:10个令人相见恨晚的R语言包
作者:yhat
大约3年前我开始使用R,起初进展很慢,与我习惯的语言相比,语法更加直观也比较简单,而且需要一段时间才能习惯于细微的差别。我还不清楚语言的力量与社区和各种包的密切关系。
和其他语言(比如 Python 和Java)相比,R可以更模糊和麻烦。好消息是,有大量的包可以在R基础库上提供简单和熟悉的界面。这篇文章是我喜欢和每天使用的10个包,并且我希望自己能早些知道他们。
1. sqldf
R语言学习曲线中最陡峭的一部分就是语法,我花了一段时间才习惯使用 <-
代替 =
。我听到很多人问 如何实现 VLOOKUP
?!?R 对于一般的数据粗加工任务非常有用,但需要一段时间才能掌握。可以认为 sqldf
是我的R”辅助轮子”。
sqldf
让你在R数据框上执行 SQL 查询。来自SAS的人会发现它非常熟悉,任何具有基本SQL技能的人都可以轻松的使用它— sqldf
使用 SQLite 语法。
install.packages(<span class="hljs-string">"sqldf"</span>) library(sqldf) sqldf(<span class="hljs-string">"SELECT day , avg(temp) as avg_temp FROM beaver2 GROUP BY day;"</span>) <span class="hljs-comment"># day avg_temp</span> <span class="hljs-comment">#1 307 37.57931</span> <span class="hljs-comment">#2 308 37.71308</span> <span class="hljs-comment">#beavers1 和 beavers2 是R base 自带的两个数据集,记录了两种海狸的体温序列</span> beavers <- sqldf(<span class="hljs-string">"select * from beaver1 union all select * from beaver2;"</span>) <span class="hljs-comment">#head(beavers)</span> <span class="hljs-comment"># day time temp activ</span> <span class="hljs-comment">#1 346 840 36.33 0</span> <span class="hljs-comment">#2 346 850 36.34 0</span> <span class="hljs-comment">#3 346 900 36.35 0</span> <span class="hljs-comment">#4 346 910 36.42 0</span> <span class="hljs-comment">#5 346 920 36.55 0</span> <span class="hljs-comment">#6 346 930 36.69 0</span> movies <- data.frame( title=c(<span class="hljs-string">"The Great Outdoors"</span>, <span class="hljs-string">"Caddyshack"</span>, <span class="hljs-string">"Fletch"</span>, <span class="hljs-string">"Days of Thunder"</span>, <span class="hljs-string">"Crazy Heart"</span>), <span class="hljs-built_in">year</span>=c(<span class="hljs-number">1988</span>, <span class="hljs-number">1980</span>, <span class="hljs-number">1985</span>, <span class="hljs-number">1990</span>, <span class="hljs-number">2009</span>) ) boxoffice <- data.frame( title=c(<span class="hljs-string">"The Great Outdoors"</span>, <span class="hljs-string">"Caddyshack"</span>, <span class="hljs-string">"Fletch"</span>, <span class="hljs-string">"Days of Thunder"</span>,<span class="hljs-string">"Top Gun"</span>), revenue=c(<span class="hljs-number">43455230</span>, <span class="hljs-number">39846344</span>, <span class="hljs-number">59600000</span>, <span class="hljs-number">157920733</span>, <span class="hljs-number">353816701</span>) ) sqldf(<span class="hljs-string">"SELECT m.* , b.revenue FROM movies m INNER JOIN boxoffice b ON m.title = b.title;"</span>) <span class="hljs-comment"># title year revenue</span> <span class="hljs-comment">#1 The Great Outdoors 1988 43455230</span> <span class="hljs-comment">#2 Caddyshack 1980 39846344</span> <span class="hljs-comment">#3 Fletch 1985 59600000</span> <span class="hljs-comment">#4 Days of Thunder 1990 157920733</span>
如果你喜欢 sqldf
,可以使用 pandasql
包来查询pandas中的 DataFrame
,通过SQL。
2. forecast
我不经常做时间序列分析,但是当我做的时候 forecast
包是我的选择。 forecast
对ARIMA,ARMA,AR,指数平滑等时间序列模型的预测简单的令人难以置信。
<span class="hljs-title">install</span>.packages(<span class="hljs-string">"forecast"</span>) <span class="hljs-title">library</span>(forecast) <span class="hljs-meta"># mdeaths: 英国每月死于肺病的人数</span> <span class="hljs-title">fit</span> <- auto.arima(mdeaths) <span class="hljs-meta">#定制你的置信区间</span> <span class="hljs-title">forecast</span>(fit, level=c(<span class="hljs-number">80</span>, <span class="hljs-number">95</span>, <span class="hljs-number">99</span>), h=<span class="hljs-number">3</span>) <span class="hljs-meta"># Point Forecast Lo 80 Hi 80 Lo 95 Hi 95 Lo 99 Hi 99</span> <span class="hljs-meta">#Jan 1980 1822.863 1564.192 2081.534 1427.259 2218.467 1302.952 2342.774</span> <span class="hljs-meta">#Feb 1980 1923.190 1635.530 2210.851 1483.251 2363.130 1345.012 2501.368</span> <span class="hljs-meta">#Mar 1980 1789.153 1495.048 2083.258 1339.359 2238.947 1198.023 2380.283</span> <span class="hljs-title">plot</span>(forecast(fit), shadecols=<span class="hljs-string">"oldstyle"</span>)
我最喜欢的特性是产生预测的时序图。
3. plyr
当我第一次使用R时,我用基本的控制运算来操纵数据(for, if, while, etc.)。我很快知道这是一个业余的做法,并且有更好的方法去实现。
在R中,apply函数族是在对列表或者向量每个元素调用函数的首选方法。虽然R基础库中有这些函数,但它们的使用可能难以掌握。我发现 plyr
包 是一个对R基础库中诸如 split
, apply
, combine
的泛函的更好用的替代。
plyr
给予你一些函数 ( ddply
, daply
, dlply
, adply
, ldply
)按照常见的蓝图:将数据结构分组拆分,对每个组应用一个函数,将结果返回到数据结构中。
ddply
拆分一个数据框(data frame)并且返回一个数据框 (所以是 dd)。 daply
拆分一个数据框并且返回一个数组(array) (所以是 da)。希望你明白这个想法。
译者注: plyr
包包含了12个命名与功能相关的函数,均以..ply命名,第一个.表示输入的数据类型(a数组 d数据框 l列表),第二个.表示输出的数据类型(_表示不输出)
install.packages(<span class="hljs-string">"plyr"</span>) <span class="hljs-keyword">library</span>(plyr) <span class="hljs-comment"># 按照 Species 拆分数据库,汇总一下,然后转换结果</span> <span class="hljs-comment"># 到数据框</span> ddply(iris, .(Species), summarise, mean_petal_length=mean(Petal.Length) ) <span class="hljs-comment"># Species mean_petal_length</span> <span class="hljs-comment">#1 setosa 1.462</span> <span class="hljs-comment">#2 versicolor 4.260</span> <span class="hljs-comment">#3 virginica 5.552</span> <span class="hljs-comment"># 按照 Species 拆分数据库,汇总一下,然后转换结果</span> <span class="hljs-comment"># 到数组</span> unlist(daply(iris[,<span class="hljs-number">4</span>:<span class="hljs-number">5</span>], .(Species), colwise(mean))) <span class="hljs-comment"># setosa.Petal.Width versicolor.Petal.Width virginica.Petal.Width</span> <span class="hljs-comment"># 0.246 1.326 2.026</span>
4. stringr
我发现R基础库的字符串功能使用起来非常困难和麻烦。Hadley Wickham编写的另一个包, stringr
,提供了一些非常需要的字符串运算符。很多函数使用那些做基础分析时不常用的数据结构。
stringr
非常易于使用。几乎所有的(和所有的重要功能)都以”str”为前缀,所以很容易记住。
install.packages(<span class="hljs-string">"stringr"</span>) <span class="hljs-function"><span class="hljs-title">library</span><span class="hljs-params">(stringr)</span></span> <span class="hljs-function"><span class="hljs-title">names</span><span class="hljs-params">(iris)</span></span> #[<span class="hljs-number">1</span>] <span class="hljs-string">"Sepal.Length"</span> <span class="hljs-string">"Sepal.Width"</span> <span class="hljs-string">"Petal.Length"</span> <span class="hljs-string">"Petal.Width"</span> <span class="hljs-string">"Species"</span> <span class="hljs-function"><span class="hljs-title">names</span><span class="hljs-params">(iris)</span></span> <- str_replace_all(names(iris), <span class="hljs-string">"[.]"</span>, <span class="hljs-string">"_"</span>) <span class="hljs-function"><span class="hljs-title">names</span><span class="hljs-params">(iris)</span></span> #[<span class="hljs-number">1</span>] <span class="hljs-string">"Sepal_Length"</span> <span class="hljs-string">"Sepal_Width"</span> <span class="hljs-string">"Petal_Length"</span> <span class="hljs-string">"Petal_Width"</span> <span class="hljs-string">"Species"</span> s <- c(<span class="hljs-string">"Go to Heaven for the climate, Hell for the company."</span>) <span class="hljs-function"><span class="hljs-title">str_extract_all</span><span class="hljs-params">(s, <span class="hljs-string">"[H][a-z]+ "</span>)</span></span> #[[<span class="hljs-number">1</span>]] #[<span class="hljs-number">1</span>] <span class="hljs-string">"Heaven "</span> <span class="hljs-string">"Hell "</span>
5. 数据库驱动的包
<span class="hljs-selector-tag">install</span><span class="hljs-selector-class">.packages</span>(<span class="hljs-string">"RPostgreSQL"</span>) <span class="hljs-selector-tag">install</span><span class="hljs-selector-class">.packages</span>(<span class="hljs-string">"RMySQL"</span>) <span class="hljs-selector-tag">install</span><span class="hljs-selector-class">.packages</span>(<span class="hljs-string">"RMongo"</span>) <span class="hljs-selector-tag">install</span><span class="hljs-selector-class">.packages</span>(<span class="hljs-string">"RODBC"</span>) <span class="hljs-selector-tag">install</span><span class="hljs-selector-class">.packages</span>(<span class="hljs-string">"RSQLite"</span>)
每个人(包括我自己)开始的时候都会这样做。你刚在首选的SQL编辑器中写了一个很棒的查询。一切都是完美的—列名都是snake case(译者注:表示单词之间用下划线连接。单词要么全部大写,要么全部小写。),日期有正确的数据类型,最后调试出了 "must appear in the GROUP BY clause or be used in an aggregate function"
的问题。你现在准备在R中进行一些分析,因此你可以在SQL编辑器中运行查询,将结果复制到csv(或者……xlsx)并读入R, 你并不需要这样做!
R对于几乎每一个可以想到的数据库都有好的驱动。当你在偶尔使用不具有独立驱动程序的数据库(SQL Server)时,你可以随时使用 RODBC
。
library(RPostgreSQL) drv <- dbDriver(<span class="hljs-string">"PostgreSQL"</span>) db <- dbConnect(drv, dbname=<span class="hljs-string">"ncaa"</span>, user=<span class="hljs-string">"YOUR USER NAME"</span>, password=<span class="hljs-string">"YOUR PASSWORD"</span>) q <- <span class="hljs-string">"SELECT * FROM game_scores;"</span> <span class="hljs-keyword">data</span> <- dbGetQuery(db, q) head(<span class="hljs-keyword">data</span>) <span class="hljs-comment">#id school game_date spread school_score opponent opp_score was_home</span> <span class="hljs-comment">#1 45111 Boston College 1985-11-16 6.0 21 Syracuse 41 False</span> <span class="hljs-comment">#2 45112 Boston College 1985-11-02 13.5 12 Penn State 16 False</span> <span class="hljs-comment">#3 45113 Boston College 1985-10-26 -11.0 17 Cincinnati 24 False</span> <span class="hljs-comment">#4 45114 Boston College 1985-10-12 -2.0 14 Army 45 False</span> <span class="hljs-comment">#5 45115 Boston College 1985-09-28 5.0 10 Miami 45 True</span> <span class="hljs-comment">#6 45116 Boston College 1985-09-21 6.5 29 Pittsburgh 22 False</span> nrow(<span class="hljs-keyword">data</span>) <span class="hljs-comment">#[1] 30932</span> ncol(<span class="hljs-keyword">data</span>) <span class="hljs-comment">#[1] 8</span>
下次你完成了完美的查询后,只需要粘贴到R里面,即可使用 RPostgreSQL
, RMySQL
, RMongo
, SQLite
, 或 RODBC
执行。不仅可以避免生成数以百计的CSV文件,在R中运行查询还可以节省I/O和转换数据类型的时间。日期,时间等会自动设置为R中的等价表示。它还使你的R脚本可重复,因此你或你团队中的其他人可以轻松获得相同的结果。
6. lubridate
在R中处理日期我从来没有幸运过。我从来没有完全掌握用POSIXs和R内建日期类型合作的方法。请用 lubridate
。
lubridate
是那些似乎 完全 按照你期望的神包之一。这些函数都有易懂的名字如 year
, month
, ymd
, 和 ymd_hms
。对于熟悉javascript的人来说,它类似于Moment.js 。
install.packages(<span class="hljs-string">"lubridate"</span>) library(lubridate) <span class="hljs-built_in">year</span>(<span class="hljs-string">"2012-12-12"</span>) <span class="hljs-comment">#[1] 2012</span> <span class="hljs-built_in">day</span>(<span class="hljs-string">"2012-12-12"</span>) <span class="hljs-comment">#[1] 12</span> ymd(<span class="hljs-string">"2012-12-12"</span>) <span class="hljs-comment">#1 按照 %Y-%m-%d 的方式解析</span> <span class="hljs-comment">#[1] "2012-12-12 UTC"</span>
这是我在一篇文章发现的非常方便的参考卡片。它涵盖了你处理日期时可能想要做的一切事情。 我还发现了这个日期速查表也可以作为一个方便的参考。
7. ggplot2
另一个Hadley Wickham的包,也许是他最知名的一个。 ggplot2
在每个人“喜爱的R包”的列表中排名很高。 它很容易使用,并且产生一些很好看的图像。 这是介绍你的工作的好方法,有很多资源可以帮助你开始使用。
- ggplot2:数据分析与图形艺术 by Hadley Wickham (Amazon)
- 从Excel到
ggplot
的罗塞塔石碑 (Yaksis Blog) - Hadley Wickham在Google的ggplot2演讲 (youtube)
- R数据可视化手册 by Winston Chang (Amazon)
8. qcc
<span class="hljs-title">install</span>.packages(<span class="hljs-string">"qcc"</span>) <span class="hljs-title">library</span>(qcc) <span class="hljs-meta"># 均值为10的序列,加上白噪声</span> <span class="hljs-title">x</span> <- rep(<span class="hljs-number">10</span>, <span class="hljs-number">100</span>) + rnorm(<span class="hljs-number">100</span>) <span class="hljs-meta"># 测试序列,均值为11</span> <span class="hljs-title">new</span>.x <- rep(<span class="hljs-number">11</span>, <span class="hljs-number">15</span>) + rnorm(<span class="hljs-number">15</span>) <span class="hljs-meta"># qcc 会标记出新的点</span> <span class="hljs-title">qcc</span>(x, newdata=new.x, <span class="hljs-class"><span class="hljs-keyword">type</span>="xbar.one")</span>
qcc
是用于 统计质量控制的库。 早在上世纪五十年代,现已不复存在的西方电气公司正在寻找一种更好检测电话线和电线问题的方法。他们提出了一系列 规则 来帮助识别有问题的线。规则观察一系列数据点的历史平均值,并且基于标准差的偏差,该规则有助于判断一组新的点是否经历均值漂移。
典型的例子是监控生产 螺母的机器。假设机器应该生产2.5英寸长的螺母。我们测量一系列的螺母: 2.48, 2.47, 2.51, 2.52, 2.54, 2.42, 2.52, 2.58, 2.51。机器出故障了吗?很难说,但上述规则可以帮助描述。
虽然你可能不会监控电话线, qcc
可帮你监控你网站的交易量,数据库的访问者或者登录名,以及其他许多流程。
9. reshape2
我经常发现,任何分析中最难的部分是把数据转化成正确的格式。 reshape2
正是Hadley Wickham的另一个软件包,专门用于 “宽”数据表 和“窄”数据表 的转换。我一般会和 ggplot2
及 plyr
一起使用它。
<span class="hljs-title">install</span>.packages(<span class="hljs-string">"reshape2"</span>) <span class="hljs-title">library</span>(reshape2) <span class="hljs-meta"># 为每一行生成唯一的ID; 这样我们可以稍后转回到宽格式</span> <span class="hljs-title">iris</span>$id <- <span class="hljs-number">1</span>:nrow(iris) <span class="hljs-title">iris</span>.lng <- melt(iris, id=c(<span class="hljs-string">"id"</span>, <span class="hljs-string">"Species"</span>)) <span class="hljs-title">head</span>(iris.lng) <span class="hljs-meta"># id Species variable value</span> <span class="hljs-meta">#1 1 setosa Sepal.Length 5.1</span> <span class="hljs-meta">#2 2 setosa Sepal.Length 4.9</span> <span class="hljs-meta">#3 3 setosa Sepal.Length 4.7</span> <span class="hljs-meta">#4 4 setosa Sepal.Length 4.6</span> <span class="hljs-meta">#5 5 setosa Sepal.Length 5.0</span> <span class="hljs-meta">#6 6 setosa Sepal.Length 5.4</span> <span class="hljs-title">iris</span>.wide <- dcast(iris.lng, id + <span class="hljs-type">Species</span> ~ variable) <span class="hljs-title">head</span>(iris.wide) <span class="hljs-meta"># id Species Sepal.Length Sepal.Width Petal.Length Petal.Width</span> <span class="hljs-meta">#1 1 setosa 5.1 3.5 1.4 0.2</span> <span class="hljs-meta">#2 2 setosa 4.9 3.0 1.4 0.2</span> <span class="hljs-meta">#3 3 setosa 4.7 3.2 1.3 0.2</span> <span class="hljs-meta">#4 4 setosa 4.6 3.1 1.5 0.2</span> <span class="hljs-meta">#5 5 setosa 5.0 3.6 1.4 0.2</span> <span class="hljs-meta">#6 6 setosa 5.4 3.9 1.7 0.4</span> <span class="hljs-title">library</span>(ggplot2) <span class="hljs-meta"># 为数据集中每个数值列绘制直方图</span> <span class="hljs-title">p</span> <- ggplot(aes(x=value, fill=<span class="hljs-type">Species</span>), <span class="hljs-class"><span class="hljs-keyword">data</span>=iris.lng)</span> <span class="hljs-title">p</span> + geom_histogram() + facet_wrap(~variable, scales=<span class="hljs-string">"free"</span>)
这是一个快速查看数据集并且获得转接的方法。你可以使用 melt
函数将宽数据转换为窄数据, 使用 dcast
将窄数据转换为宽数据。
10. randomForest
如果这个列表不包括 至少一个 能你的朋友震惊的机器学习包就不会完整。随机森林 是一个很好的算法。它很容易使用,可以进行监督学习或者无监督学习,它可以与许多不同类型的数据集一起使用,但最重要的是 它的高效率! 这是它在R中的使用方法。
install.packages(<span class="hljs-string">"randomForest"</span>) library(randomForest) <span class="hljs-comment"># 下载泰坦尼克号幸存者数据集</span> <span class="hljs-keyword">data</span> <- read.table(<span class="hljs-string">"http://math.ucdenver.edu/RTutorial/titanic.txt"</span>, h=T, sep=<span class="hljs-string">"\t"</span>) <span class="hljs-comment"># 将Survived列转为yes/no因子</span> <span class="hljs-keyword">data</span><span class="hljs-variable">$Survived</span> <- as.factor(ifelse(<span class="hljs-keyword">data</span><span class="hljs-variable">$Survived</span>==<span class="hljs-number">1</span>, <span class="hljs-string">"yes"</span>, <span class="hljs-string">"no"</span>)) <span class="hljs-comment"># 拆分为训练集和测试集</span> idx <- runif(nrow(<span class="hljs-keyword">data</span>)) <= .<span class="hljs-number">75</span> data.train <- data[idx,] data.test <- data[-idx,] <span class="hljs-comment"># 训练一个随机森林</span> rf <- randomForest(Survived ~ PClass + Age + Sex, <span class="hljs-keyword">data</span>=data.train, importance=TRUE, na.action=na.omit) <span class="hljs-comment"># 模型中每个变量的重要程度</span> imp <- importance(rf) o <- order(imp[,<span class="hljs-number">3</span>], decreasing=T) imp[o,] <span class="hljs-comment"># no yes MeanDecreaseAccuracy MeanDecreaseGini</span> <span class="hljs-comment">#Sex 51.49855 53.30255 55.13458 63.46861</span> <span class="hljs-comment">#PClass 25.48715 24.12522 28.43298 22.31789</span> <span class="hljs-comment">#Age 20.08571 14.07954 24.64607 19.57423</span> <span class="hljs-comment"># 混淆矩阵 [[真反例, 假正例], [假反例, 正正例]]</span> table(data.test<span class="hljs-variable">$Survived</span>, predict(rf, data.test), dnn=list(<span class="hljs-string">"actual"</span>, <span class="hljs-string">"predicted"</span>)) <span class="hljs-comment"># predicted</span> <span class="hljs-comment">#actual no yes</span> <span class="hljs-comment"># no 427 16</span> <span class="hljs-comment"># yes 117 195</span>
End.
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 10个令人相见恨晚的R语言包
- 10个令人相见恨晚的R语言包
- 相见恨晚的 Erlang
- 相见恨晚的 Lodash 函数:Object
- 爱了!安利一个相见恨晚的可视化学习网站
- 10个让你相见恨晚的iOS Swift动画框架!
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
JavaScript DOM高级程序设计
Jeffrey Sambells、Aaron Gustafson / 李松峰、李雅雯 / 人民邮电出版社 / 2008-7 / 59.00元
本书注重理论与实践的结合,全面讲述高级的DOM 脚本编程。全书分为3 个部分:第一部分“深入理解DOM 脚本编程”,涉及W3C DOM 规范的各方面,包括非标准的浏览器支持和不支持的内容;第二部分“浏览器外部通信”,以Ajax 和客户端—服务器端通信为主题;第三部分“部分高级脚本编程资源”,集中介绍了一批第三方脚本编程资源,包括库和API。同时,每部分的最后一章都为案例研究,将学到的内容应用于实践......一起来看看 《JavaScript DOM高级程序设计》 这本书的介绍吧!