【SAS Says】基础篇:开发数据

特别说明:本节【SAS Says】基础篇:开发数据,用的是数说君学习《The little SAS book》时的中文笔记,我们认为这是打基础的最好选择。

转载请在文章开头注明微信号:shushuojun,谢谢!

复习:

前面五节

  • 【SAS Says】基础篇:SAS软件入门(上)
  • 【SAS Says】基础篇:SAS软件入门(下)
  • 【SAS Says】基础篇:读取数据(上)
  • 【SAS Says】基础篇:读取数据(中)
  • 【SAS Says】基础篇:读取数据(下)

在微信号“shushuojun”中回复“SAS”查看。

前面我们介绍了各种用SAS读取数据的知识,现在数说君考你两个问题:

(1)有一个TXT数据文档,如何让SAS只读取第3到第5行的数据?

(2)我们一般读取的数据都是逗号分隔的,现在有一个数据文件是制表符分隔的,那么要怎么读取,或者说要用到什么命令?

如果答不上来,回复“SAS”查看前面的内容。本节讲的是如何开发数据——如何使用SAS的函数、如何用if-then语句、如何处理SAS烦人的日期格式、如何使用retain语句让SAS保存前一次变量的值、如何快捷的列出SAS的变量名等等。

本节目录:

开发数据

3.1 创建并重新定义变量

3.2 使用SAS函数

3.3 使用IF-THEN语句

3.4 用IF-THEN语句将观测值分组

3.5 构造子集

3.6 处理SAS的日期数据

3.7 可选择的数据格式和函数

3.8 使用retain和sum语句

3.9 用数组简化程序

3.10 列出变量名的快捷方式


开发数据

3.1 创建并重新定义变量

可以通过分配语句来创建并重新定义变量,基本形式为:

Variable=expression

Variable是变量名,expression可以是常量、其他变量、或者数学表达式。分配语句的基本类型有:

Expression是数学表达式时,需要遵循运算法则,先算指数、再算乘除、之后是加减。可以用括号改变运算等级。

例子 如下是一个农产品估重数据,每位农民要求对他们的番茄、南瓜、豌豆、葡萄进行估重:

下面代码从garden.dat原始文件中读取数据,并进行修改:

这个程序包含了5句分配语句,第一个将14赋值给zone,第二个使type等于一个字符串常量……打印出的结果中,既包括旧变量,又包括新变量:

由于观测值susan的peas变量出现了缺失值,因此这个观测值的total和pertom变量也出现了缺失值。日志窗口的说明如下:

NOTE:Missing valueswere generated as a result of performing an operation onmissing values.

3.2 使用SAS函数

SAS有400多个函数,主要涵盖如下领域:

函数基本形式:function-name(argument,argument,…),所有的函数都需要括号,即使没有参数。下面的程序计算使用MDY函数,MDY函数需要三个参数:月、日、年。

Birthday=MDY(MonthBorn,DayBorn,YearBorn);

函数可以嵌套,即一个函数可以是另一个函数的参数。比如:NewValue=INT(LOG(10));

例子 有一个南瓜雕刻比赛的数据,pumpkin.dat数据包含了参赛者的名字、年龄、雕刻的南瓜类型、报名日期、五位裁判给出的分数。

下面的代码读取了数据、创建了两个新变量、转换了一个大小写:

AvgScore 使用均值函数创建的变量,计算参数的均值,这与直接相加再除以5不同的地方在于,当参数中出现缺失值时,直接相加再除的方法返回缺失值,而均值函数计算非缺失参数的均值。

DayEntered变量使用DAY函数,返回日期在一个月里的天数。

Type用大写转换函数将原来的字母转换成大写字母。

结果是:

3.3 使用IF-THEN语句

条件语句IF-THEN的基本形式为:IF 条件 THEN 执行;

比如:IF Model='Mustang' THEN Make='Ford';

条件语句中的一些基本比较符号:

还有IN比较符,比如这句中IF Model IN('Corvette','Camaro') THEN Make='Chevrolet';代表当Model为Corvette或Camaro的时候,将Chevrolet赋给Make。

一个条件只能有一个执行,如果要多个执行,则需要DO和END关键字。

可以用AND和OR来定义多个条件:IFModel='Mustang' AND Year<1975 THEN Status='classic';

例子 如下的数据包含了模型的名字、年份、制造商和颜色:

下面的代码从cars.dat的原始文件中读取数据,使用IF-THEN语句填满缺失值,并创建一个新变量Status

输出结果如下:

3.4 用IF-THEN语句将观测值分组

IF THEN/ELSE的一般形式为:

IF condition THEN action;

ELSE IF condition THEN action;

ELSE IF condition THEN action;

用else语句与直接用多个IF-THEN语句比起来,有两个优势,第一是更有效率,电脑将占用更少的时间;第二是else可以确保你的两个condition之间互斥。

有时候最后一个ELSE只有action,没有IF-THEN:

例子有一个住房改善的数据,home.dat,包括了姓名、改善工作、改善成本:

下面的代码读取数据,并新建了一个CostGroup的变量。根据Cost的值将数据分成high、medium、low和missing三类:

输出结果是:

3.5 构造子集

IF语句可以构造子集,取数据集中的部分数据。

基本形式为: IF expression; 比如: IF Sex='f';

如果IF条件中的数据是真,则数据步将继续执行。

还可以使用DELETE语句,来删除哪些不要的数据: IFexpression THEN DELETE;

这两句话是等价的: IF Sex='f'; IF Sex='m'THEN DELETE;

例子 有关于莎士比亚歌剧的清单,Shakespeare.dat,包含歌剧名、首次表演年份、类型:

下面的代码读取数据,并且用IF语句构造一个只包含喜剧(comedies)的子集:

输出结果如下:

观察日志有时能很好的保证我们截取了我们要的数据:

在这个例子中,用DELETE等价的语句为:

IF Type='tragedy' OR Type='romance' OR Type='history' THEN DELETE;

3.6 处理SAS的日期数据

日期数据的处理很棘手,有的月份有31天、有的30天、有的28天。SAS简化的日期数据,将所有的日期转化成一个以1960年1月1日为起点的数。比如:

SAS处理日期数据的三个工具为:读取数据的informats,使用数据的函数(functions),打印数据的formats

Informats 读取日期数据需要用formatted input。比如,如何告诉SAS用MMDDYY10. imforat读取名为BirthDate的变量:

INPUT BirthDate MMDDYY10.;

设定默认的百年 07/04/76这样的数据可能是1976,也可能是2076、1776。因此需要YEARCUTOFF=来指定一个一百年的第一年,默认的是1920年。下面的语句就是告诉SAS将一个两位年份的日期解释为1960年到2049年之间:

OPTIONS YEARCUTOFF=1950;

SAS表达式中的日期一旦被以SAS日期格式读取之后,可以将此数据想其他数值数据一样用在表达式中。比如像为图书馆的书设定21天的还书日期,只需要在结束日期上加上21:

OPTIONS YEARCUTOFF=1950;

通过在表达式中加入引号和字母D,可以将一个日期当做常数来使用,如下的代码创建了一个EarthDay05的变量,并且等于April22,2005

EarthDay05='22APR2005'D;

函数 SAS日期函数使得操作大大简便,比图today()返回今天的日期。

语句DaysOverDue=TODAY()-DateDue;可以计算一本书应归还还剩余的期限。

Fomats 打印日期数据时,还需要将数值换成日期,下面的FORMAT语句告诉SAS用WEEKDATE17.格式打印变量BirthDate。

FORMAT BirthDate WEEKDATE17.;

例子 图书馆有借书卡数据,Dates.dat,包含持卡人姓名、出生日期、卡办理日期。

下面的代码读取数据,计算变量使用期限(expiredate),使用期限为3年;变量expirequarter计算使用期限的四分之一,使用函数QTR()。接着用IF语句来判断一个卡是否为新卡,在2003年1月1日之后办理的,为新卡:

输出结果为:

注意BirthDate没有用日期格式。

3.7 可选择的Date Informats,Functions和Formats

下面是例子:

3.8 使用retain和sum语句

当开始数据步的每一个观测值迭代时,SAS会先将所有变量值设为缺失,再通过input和分配语句改变。Ratain和sum语句可以改变这种方式,

Retain语句 retain语句可以让SAS保存前一次变量的值。它可以出现在数据步的任何位置,基本形式为:

RETAIN variable-list;

也可以指定一个初始值,而不是用缺失值或前一次的值代替初始值

RETAIN variable-list initial-value;

Sum语句 SUM语句用于你想将一个表达式的值累加到一个变量上去时,基本形式为:

variable+expression;

这个语句将表达式的值赋给变量,同时将变量的值保留到下一次迭代。这个变量必须是数值型,且初始值为0。因此,语句等价于如下形式:

RETAIN variable 0;

variable=SUM(variable,expression);

例子 有一个关于本赛季棒球比赛的数据,games.dat,包含比赛日期、参赛队伍、hit数据、runs数据

现在需要增加两个变量,一个反应本赛季的总runs数,一个反应一场比赛中最大的runs数。下面的代码用sum语句实现总run数,用retain和max函数实现最大runs数:

变量maxruns取前面迭代的maxruns和runs中最大值;变量runstodate将每一场比赛的runs都加到自己身上。结果如下:

3.9 用数组简化程序

对于太多变量要处理的程序,数组将大大简化程序。

SAS中,数组是一组变量,变量可以是已存在的,也可以是新创建的。

数组在数据步中用ARRAY来定义,基本形式为:

ARRAY name(n) $ variable-list;

Name是数组名,n是变量数,()也可以用[]和{}代替。如果变量是字符串,则需要$,且变量是新创建的字符串时,$是必须的。变量名依照顺序排列,如数组:

ARRAY store(4) Macys Penneys Sears Target;

则store(1)是Macys,store(2)是Penneys,store(3)是Sear,store(4)是Target。

数组本身不储存在数据集中,只有在数据步中才被定义。命名规则与变量一样(不超过32字节,以字母、下划线开头,只能包含字母、数字、下划线)

例子 广播电台wbrk做了一份关于歌曲的听众调查,对10首歌进行打分,分值在1-5,如果没听过则填9。数据文件wbrk.dat包括了被访者姓名、年龄、以及十首歌的打分。

下面的代码将所有打分为9的改为缺失值:

十首歌被放入song的数组中。输出结果如下:

注意这里数组没有被保存到数据集中,而i被保存了。

3.10 列出变量名的快捷方式

如果想把100个变量放入数组,并不需要一个一个变量名的输入,有快捷方式可以列出变量名。

Number range lists 开始于同一个单词,结尾于连续的数字的,可以使用Numberrange list。比如:

Name range lists这种列表是依据变量在数据集中的排列顺序来的,比如,创建如下数据步:

则变量的排列顺序就为:Y A C H R

那么可以依照这个顺序用“put 第一个变量--最后一个变量”来简化:

如果不能确定数据集中变量的顺序,可以用proc contents的postion选项来查看。下面的代码列出了永久数据集distance的变量顺序:

例子 广播电台WBRK想要修改前面的代码(将9改为缺失值),使用mean函数计算平均分数:

程序中,当原始变量(domk-ttr)值为9时,song变量值为缺失值,否则就把原始变量的值赋给song变量。另外avgscore计算平均值:

原文发布于微信公众号 - 数说工作室(shushuojun)

原文发表时间:2015-06-26

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏QQ音乐技术团队的专栏

Android Native 开发之 NewString 与 NewStringUtf 解析

本文将从一个 Native Crash 分析入手,带大家了解我们平时开发中,那些容易忽略但又很值得学习的底层源码知识。

1.4K9
来自专栏用户2442861的专栏

Java 8系列之重新认识HashMap

作者:美团点评技术团队 链接:https://zhuanlan.zhihu.com/p/21673805 来源:知乎 著作权归作者所有。商业转载请联系作者...

1111
来自专栏小樱的经验随笔

华中农业大学第五届程序设计大赛网络同步赛题解

A.Little Red Riding Hood ? B.Choosy in Food •F[i]:从第I个点到终点的期望步数 •F[i] = (F[i +...

3537
来自专栏用户2442861的专栏

典型的Top K算法_找出一个数组里面前K个最大数...或找出1亿个浮点数中最大的10000个...一个文本文件,找出前10个经常出现的词,但这次文件比较长,说是上亿行或十亿行,总之无法一次读入内存,

http://blog.163.com/xychenbaihu@yeah/blog/static/1322296552012821103039741/

5132
来自专栏计算机视觉与深度学习基础

Leetcode 164 Maximum Gap 桶排序好题

Given an unsorted array, find the maximum difference between the successive ele...

2135
来自专栏趣谈编程

外部排序

当我们要排序的文件太大以至于内存无法一次性装下的时候,这时候我们可以使用外部排序,将数据在外部存储器和内存之间来回交换,以达到排序的目的

1600
来自专栏阿凯的Excel

八种方式实现多条件匹配

之前在Excel内部的分享交流群和别的讲师探讨了多条件匹配有哪些实现方式。 围观的市民刘先生表示:我活了二十多年,看见斗图的比较多,这么无聊斗Excel使用技巧...

3424
来自专栏mathor

TRIE(3)

 搜索引擎现在一般都有关键词提示或者说是补全功能。就是当你在搜索框里输入一个关键词s时,搜索引擎会自动提示你一些频率比较高,同时前缀是s的关键词  这道...

982
来自专栏大数据挖掘DT机器学习

【知识】SAS数据分析完整笔记(3)

SAS学习笔记(3):SAS一般高级语言 本篇SAS读书笔记主要介绍SAS一般高级语言,主要内容包括赋值语句、输出语句、分支机构、循环结构、数组以及函数等六个...

4259
来自专栏小红豆的数据分析

小蛇学python(16)numpy高阶用法

如果只是从事简单的数据分析,其实numpy的用处并不是很大。简单了解一下numpy,学好pandas已经够用,尤其是对于结构化或表格化数据。但是精通面向数组的编...

1492

扫码关注云+社区

领取腾讯云代金券