在SAS里玩穿越 | 【SAS Says·扩展篇】IML:穿越 | 数说·语言

2018-04-08 10:53:00 浏览数 (1)

一直以来,大众了解的SAS都是数据集操作,使用的方法是数据步和过程步。但其实,SAS这个庞大的系统中还隐藏了另一个平行世界——IML,在这个世界里,你需要一个像操作MATLAB一样的矩阵思维。 今天我们将介绍如何在SAS里玩穿越,将数据从矩阵变成SAS数据集,从SAS数据集再变成矩阵。它将大大方便我们的使用。


在SAS里玩穿越 | 【SAS Says·扩展篇】IML:穿越

本文要解决三个问题:

第一个问题:如何把SAS数据集转换为矩阵来处理?

把数据集转换成矩阵来,在很多情况下处理起来会方便得多,比如可以轻易的实现“如果第三行第五列的数字比第三行第六列的数字大,就把第二行第七列的数字增加1”这种问题。当然,方便的地方还远远不止这些。

第二个问题:如何把矩阵转换成数据集来处理?

SAS的优势在于强大的统计模块,无论是回归、检验,还是数据管理SQL,甚至是贝叶斯,都可以方便快速的实现,因此,将矩阵转换成数据集来做统计分析,真好。

第三个问题:如何直接在IML模块中处理数据集?

当然,IML模块也提供了直接编辑数据集的功能。

最后再来一个附加问题:如何直接读入外部的文件。

好了,让我们一块来探索一下吧!

本集学习完之后,SAS的IML模块就告一段落,最后面是Ansta给自己布置的一道作业,大家可以一起来做一下,然后相互交流~


第一个问题:将SAS数据集转换为矩阵

Read语句可以将数据集转化为矩阵,但前提是数据集必须已经打开,而打开数据集用use或edit,即:

红色为必须语句,黄色为可选语句。首先要用use或edit语句将数据集打开,然后再用read语句转换成矩阵。

我们来看一个例子:

SAS自带的数据,在sashelp逻辑库下有一个class数据集:

我们现在要将所有男性数据读入矩阵boy中:

proc iml; use sashelp.class; read all into boy where(sex="男"); print class; quit;

Var,选择的变量不填,SAS就默认把所有数值型变量读入矩阵,生成一个数值矩阵。也可以手工选择字符矩阵:

proc iml; use sashelp.class; read all var {name sex} into boy2 where(sex="男"); print class; quit;

好,第一个问题就这么愉快的结束了。

第二个问题:将矩阵转换为数据集

和数据集转换成矩阵差不多,将矩阵变成数据集,也需要先打开一个新数据集,也就是创建一个数据集(create语句),然后讲矩阵放到这个数据集中(append语句):

我们把前面包括年龄、身高、体重三个变量的矩阵boy写入数据集。

在写入数据集之前,首先生成一个ID变量,,一遍标识出不同的人,方法就是用第一讲用到的水平连接符,复习→:

proc iml; use sashelp.class; read all into boy where(sex="男"); id={1,2,3,4,5,6,7,8,9,10}; id_boy=id||boy; create boy var {id age height weight}; append from id_boy; quit;

矩阵变成数据集之后,就可以用SAS的各种强大的统计模块做分析了。

好,第二个问题也就这么愉快的结束了!

第三个问题:直接在IML模块中处理数据集

首先我们也还是要使用use语句打开数据集。

(1)列出观测值

List 观测值范围 var {选择变量名} where (条件) ;

(红色背景是必须要有的,黄色背景是可以省略的)

观测值范围

  • All:所有观测值
  • Current:当前观测值
  • Next:下一个观测值
  • After:当前观测值之后的所有观测值
  • Point 记录号:指定观测值

以逻辑库SAShelp中的air数据集为例:

我们试一下读取所有international airline travel小于120的观测值,和只读取第6行的观测值:

proc iml; use sashelp.air; list all where (air<120); quit;

proc iml; use sashelp.air; list point 6; quit;

(2)删除观测值

use 数据集; edit 数据集; delete 观测值范围 where(条件);

(红色背景是必须要有的,黄色背景是可以省略的,下同,不再重复)

观测值范围和上面的差不多:

  • Point 记录号:删除某行数据。
  • All 删除所有观测值。

有一份10人的score数据,数据集的名字叫score

现在想删除第二个人James的记录。

proc iml; use score; list all; edit score; delete point 2; list all ; quit;

可以看出,当删除之后,James不见了。

(3)数据排序

close 数据集; sort 数据集 out=排序后的数据集 by descending 排序变量

对一个数据集进行排序,首先要保证它不是打开状态,因此要用close语句关闭掉。

仍然对sashelp中的air数据排序,按照变量international airline travel (thousands)来排序(对应变量名为AIR):

proc iml; close sashelp.air; sort sashelp.air out=sorted by descending air; quit;

执行语句后,生成了一个降序排列的sorted数据集。

(4)简单统计分析

IML模块可以直接对数据集进行简单的描述性统计。

use 数据集; summary var {变量1 变量2 ...} class {分类变量1 分类变量2 ...} stat {mean std};

Class语句选择分类变量,如想分性别查看,stat列出需要的统计量,如果不列的话默认给出:min、max、mean、std

如还是air这个数据,想看international airline travel的均值和方差:

proc iml; use sashelp.air; summary var {AIR} stat { mean std }; quit;

最后的一个附加问题:如何读入外部文件?

步骤是这样的:

用infile语句将外部文件读入SAS;

用create语句创建一个SAS数据集;

用do data-append-end语句将外部文件装进SAS数据集中,举个例子:

现在有外部文件d:testSet.txt,想要读入SAS,变量名分别为a、b、c

proc iml; infile 'D:testSet.txt'; create temp var {a b c}; do data; input a b c; append; end; close temp; quit;

这样,文件就读入SAS的work逻辑库中,数据集名字为temp。

作业: 用两种方法实现如下数据的回归分析

Sashelp逻辑库中有一个关于GNP的数据sashelp.gnp,要求用1961、1962、1963三年的数据建立回归模型:

GNP = consump invest

用的变量有:

  • GNP-gross national product ($billions)
  • Consump-personal consumption expenditures
  • Invest-gross private domestic investment

要求给出系数、R2、t检验的p值,提示:

SAS常用的的概率密度函数

①标准正态分布函数PROBNORM(x)

计算服从标准正态分布的随机变量u小于给定x的概率。即p(u<X)。如:

y=PROBNORM(-2.58),结果为0.005。

②t分布概率函数PROBT(x,df,nc)

计算自由度为df,非中心参数为nc的t分布随机变量小于给定值x的事件的概率,当nc=0或不规定这项时,分布为中心分布。如y=probt(0.95),结果为0. 975。

③F分布概率函数PROBF(x,dfl,df2,nc)

计算服从分子自由度为dfl,分母自由度为df2的F分布的随机变量小于给定值x的事件的概率,当分布为中心分布时,nc=0或不规定该项。

这是Ansta给自己布置的作业,大家也可以试一试,再对照proc reg的结果看一下,之后会给出我自己修改的代码,我也是在学习,希望能和大家一起交流。

sas

0 人点赞