Yihui Xie

S-Plus/R软件使用攻略

谢益辉 / 2005-10-18


关于统计软件和S-Plus,黄思思催我写篇稿子,昨晚花了四个小时写完,先发布于此吧。


关于S-Plus(R),想写点东西的念头由来已久,因为据我观察,我们统计学院的学生似乎对编程存在某种情绪,大家都不太愿意编程序。在正式内容开始之前,我先就程序在统计中的作用以我个人的理解啰嗦两句吧。

我们已经有很多种具有很好的用户界面(UI)的统计软件,点着鼠标就可以轻松完成统计分析,比如SPSS、MINITAB,甚至Excel等,那为什么要学习编程呢?我认为这其中有两点原因:

一是因为我们需要适当了解统计分析的过程。对于现在的统计软件及其应用,用“泛滥”这个词来形容并不过分。统计软件正在朝“傻瓜式”的方向发展,现在的“傻瓜”意味着不管你怎么点鼠标,软件都能给你运算出来所谓的统计分析结果。人们看见出来的结果中有”df”,”Sig. (2-tailed)”,”95% Confidence Interval of the Difference”等,于是就吓坏了,心想,多么神奇啊,多么科学啊,可能他们所谓的“科学”就是指大家谁都看不懂的东西吧。傻瓜式的东西其实就是把分析计算过程隐藏在一个Black Box中,我们把任何东西都扔进这个Black Box都能产生结果,当然,把奶牛、轮胎、衣架扔进去是不行的,我是指数据。我们学习编程,目的就是清楚计算过程,进而更加深刻地理解统计方法,更重要的是理解统计方法应用的背景前提条件以及计算出来的结果的含义

二是因为统计软件的发展要适应统计方法发展的需要,尤其是一些特殊方法。任何一门学科的发展,都必须要有不断的创新,统计也不例外,并且大量的统计分析也依靠着计算机来完成;在这个时代,庞杂的手工计算是难以想象的。新方法的产生,应该有相应的统计程序在计算机上实现,而现实并非如此。举个例子,比如我们多元统计分析中的有序样品聚类分析,我就没找到相应的SPSS分析方法(不知是否有License的问题),后来只好自己用S-Plus写了这个程序。不仅是这些经典的方法,我们平时自己发现而软件上没有的统计方法,都可以用编程的方法来自己实现。这里附带说一句,现在大三上非参数统计的同学们可能“受苦”了,你们使用的很多非参的方法其实S-Plus中有现成的函数,但你们也应该听王星老师教导,“安分守己”一些,认真编程序,多锻炼锻炼吧。

下面就具体针对S-Plus编程说一点自己学到的S-Plus程序知识吧,仅供参考。

一、程序通常的组成部分

完整的程序一般包括三部分,这是经典程序书籍中必然要提到的:算法(灵魂)+数据结构(对象)+语言环境(工具)。

对于所谓算法,我觉得知道三种结构就已经足够了:顺序、选择和循环。这是三种基本的程序机构,顺序结构没什么好说的,原程序是什么顺序就怎样执行;选择结构用得较多的就是if(test) {true.expr} else {false.expr},这也是很明了的结构,当然还有switch()函数,有兴趣的同学去查帮助吧;循环无非就是for (name in values) {expr},至于while()等都可以自己看相应的帮助。

对于数据结构,在S-Plus中用得最普遍的就是向量(Vector)和矩阵(Matrix),掌握了这两种数据结构的使用,可以说S-Plus的数据结构就算基本掌握了,此外List也是比较常用的,像data.frame什么的,说句实在话,用得不多。向量一般通过函数c()来产生,矩阵则是matrix(),其中的元素用方括号“[]”来读取,方括号中的下标可以极其灵活地使用,比如a是一个向量,那么a[3:5]则表示a中第3到第5个元素组成的向量;同样,对于一个矩阵a,a[3:5,]表示矩阵的第3到5行,尤其是下标为负数时,表示从数据中去除相应位置的元素,例如a[-2]表示去除向量a的第2个元素。后面我要着重要强调三种括号“()”“[]”“{}”的用法。

语言环境当然指S-Plus的特殊语言规定了,比如语法等。之所以提到语言环境,是为了说一下R和S-Plus的区别:目前就我一点浅薄的了解,语法方面似乎R只是在S-Plus中把赋值符号“_”改为了“=”(对于S-Plus中的“<-”和“_”我愤愤已久,很BT的规定);当然这点区别没什么大的意义,还有很多其他方面的区别,比如S-Plus有Data Set,而R没有,等等,就不多说了。总之R跟S-Plus语法上几乎完全是一样的,所以我在标题中把它们俩放在一起来说。当然,用哪种软件没关系,重要的是程序思想(这是独孤求败的剑冢给我们的启示啊)。

二、程序为什么出错

辛辛苦苦编出程序,Run一下,发现有Syntax Error(句法错误)或者Object … not found(变量未定义而出错,但注意函数中的参数不用再定义),不禁要抓狂……

程序的错误只要不是逻辑思维上的错误,那就不是什么严重错误,首先我们自己要保证自己逻辑的正确性,对于一些“技术性”的错误,处理起来还是很容易的,我自己大致总结了一下我们容易犯的错误:

  1. 当年VB“毒害”了我们的语法习惯

    有天晚上徒弟大人就跑过来愤愤地问我VB学了干嘛的,为什么现在又改用S-Plus,我目前只能解释为S-Plus更适合统计编程,但是我看到我们脑中VB的语法对现在S-Plus的语法影响确实比较大。比如S-Plus中赋值符号“<-”或“_”常被误写成“=”,逻辑相等符号“==”常被误写为“=”(记好!S-Plus中几乎没有用“=”的地方),逻辑“非”“!=”误写为“<>”,逻辑“或”“|”误写为“or”,逻辑“和”“&”误写为“and”等等。

  2. 括号不配对

    我们编写的程序大多也都比较长,于是常常出现括号不配对的情况。好在S-Plus的Script中有自动配对括号的功能,当键入回括号时,前面相应的括号会反显闪动,我们可以利用这一点来检查括号是否缺失。

  3. 循环下标出界

    由于我们的程序中经常用到向量和矩阵作循环,循环下标出界也是常见的错误。如果程序运行遇到什么“疑难杂症”或者莫名其妙的错误,可以检查一下是否属于这种错误。

三、括号的用法

基本就三句话:()里面放函数的参数,[]获取数组或者向量的元素,{}放结构程序段。比较特殊的是“[[]]”,这是在List型数据中使用的,表示一个List的某一个位置的数据对象,大家可以试试看geyser[[1]]或者geyser[[2]]表示什么。

四、两个强烈建议——使用函数和帮助

  1. 关于函数

    我编出来的程序经常挨大家骂,因为我总是使用一些大家不知道的函数,大家觉得读不懂,但是我的目的是为了简化程序,本来编程就是一件让人很头大的事情,能抄近路就抄啊!所以我大力提倡大家使用一些很便利的函数如seq(),rep(),%%,%/%,%*%,abs(),sqrt(),对于我们统计专业的同学,更是应该掌握一些基本的统计函数,如sum(),mean()等,还有大量的分布函数如chisq,t,norm等,也是必需要掌握的。

  2. 使用帮助

    对于帮助,我不得不说,在下实在是很想不明白,为什么大家能咬牙背完红宝书、TOFEL词汇,却仍然惧怕英文帮助呢?这是多么大一块宝藏啊!可惜我们都不利用。一定要记得,养成在问别人之前先问帮助的习惯。

    S-Plus帮助文件

好了,不敢多啰嗦了,谢某本来就是个很啰嗦的人。只是希望大家看了这些文字之后不要再犯if(a=3){…}这样的错误,如果能写出for(i in 10:1){…}这样的程序(要学会灵活运用程序语法!),那我再高兴不过。也欢迎大家在此跟我讨论,什么都可以谈,八卦除外。

附:一些教程PDF版本下载以及R 2.1.1 Windows版下载地址