---
title: S-Plus/R软件使用攻略
date: '2005-10-18T17:02:00+08:00'
slug: 17-02-00
---

关于统计软件和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帮助文件](https://db.yihui.org/images/shelp.jpg)

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

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

- [SAS+S-Plus教程](http://cn.math.pku.edu.cn/teachers/lidf/docs/statsoft/PDF/web.pdf)（北京大学数学科学学院李东风）
- S-Plus教程（北京大学数学科学学院李东风）
- S-Plus教程（中国科大 孟强）（写得不错）
- R 2.1.1 Windows版[下载](http://cn.math.pku.edu.cn/teachers/lidf/download/R/rw2011.exe)（25.4M）
