SAS 循环与数组
SAS 循环与数组
SAS提供了循环语句以满足在编程中需要多次执行相同操作的情 况。有时还需要对不同的变量执行相同的操作,此时可定义SAS数组,并通过数组名和下标来引用这些变量。
1 循环
SAS循环语句通常有如下几种形式:迭代DO语句、DO WHILE语句 和DO UNTIL语句。
1.迭代DO语句
迭代DO语句的基本形式如下:
- DO 索引变量=开始值 <TO 结束值> <BY递进值> <WHILE(表达式)> <UNTIL(表达式)>;
- … SAS语句…
- END;
其中:
- ·索引变量用于指定一个变量,若该变量不存在,则创建新变量。DO语句和END语句之间的语句称为DO组,索引变量的值会控制DO组 的执行。
- ·开始值指定索引变量的初始值,可以是表达式或表达式序列。DO组的执行从“索引变量=开始值”开始。在循环的第一个迭代开始前,对开始值求值。如果结束值和递进值不存在,那么开始值可能是一系列 项,则DO语句的形式如下。
- DO 索引变量=项1 <, …项n>;
项1~项n可以是数字常量、字符常量或变量。SAS为列表中的每个 项执行一次DO组。
- ·结束值指定索引变量的结束值。当开始值和结束值都存在时,DO 组执行直到下面任意一种情况发生时循环执行结束:索引变量的值超过 结束值;DO组中存在指示退出循环的语句,例如LEAVE语句、GO TO 语句;如果有WHILE或UNTIL选项,则WHILE之后的表达式不满足或 UNTIL之后的表达式满足(可参考后面对DO UNTIL语句和DO WHILE 语句的介绍)。
- ·递进值指定一个数字,或者是产生数字值的表达式,来控制索引 变量的增量。递进值在循环执行前进行计算。因此,在DO组内对递进 值的修改不会影响循环迭代次数。每次迭代后,索引变量的值为其当前 值的基础上增加递进值。如果未指定递进值,则索引变量的值增加1。
- data work.square;
- do x= to by ;
- y = x**;
- output;
- end;
- run;
- proc print data=work.square;
- run;
2. DO UNTIL语句
DO UNTIL语句重复执行DO循环中的语句,直到条件为真。DO UNTIL语句的基本形式如下:
- DO UNTIL (表达式);
- ...SAS语句...
- END;
表达式可是任意的SAS表达式。DO UNTIL语句中至少包含一个表 达式,也可以包含多个表达式。在DO循环中的语句执行完成后将对表 达式求值。所以,DO循环至少被执行一次。
将给定字符串中包含的各个单词分开写入数据集中。 在DO循环中使用SCAN函数依次读取字符串中的单词,并存储在变量word中且输出。LENGTHN函数用于判断循环结束的标志。当SCAN 函数扫描到字符串结尾,word值为空时,LENGTHN函数返回0,循环 结束。
代码如下:
- data work.all;
- length word $;
- drop string;
- string='The quick brown fox jumps over the lazy dog.';
- do until(lengthn(word)=);
- count+;
- word=scan(string, count);
- output;
- end;
- run;
- proc print data=work.all noobs;
- run;
3.DO WHILE语句
DO WHILE语句在条件为真时重复执行DO循环。DO WHILE语句 的基本形式如下:
- DO WHILE (表达式);
- ...SAS语句...
- END;
表达式可是任意的SAS表达式。DO UNTIL语句中至少包含一个表 达式,也可以包含多个表达式。在DO循环中的语句被执行前先对表达式求值。如果第一次执行时表达式为假(false),DO循环不会被执行。
将给定字符串中包含的各个单词分开写入数据集中。 代码如下:
- data work.all;
- length word $;
drop string;
string='The quick brown fox jumps over the lazy dog.';- word=scan(string, );
- do while(lengthn(word)>);
- count+;
- word=scan(string, count);
- output;
- end;
- run;
因为要WHILE表达式必须成立才会执行DO循环,也就是说在执行 到DO WHILE语句之前,word不能为空或缺失值,所以代码中先对word 值赋值(word可以赋值为其他任何不为空的字符值)。DO循环中,当 SCAN函数扫描到字符串结尾,word值为空时,LENGTHN函数返回0,不满足条件lengthn(word)>0,循环结束。所生成的数据集与例3.25的 结果一样,这里不再给出。
下面是对3种循环语句的比较:
- ·迭代DO语句基于索引变量值重复执行DO语句和END语句之间的SAS语句。使用迭代DO语句较容易控制循环次数。
- ·DO UNTIL语句重复执行在DO循环中的语句,直到条件为真。DOUNTIL语句在每次DO循环迭代结束后检查条件。
- ·DO WHILE语句在条件为真时重复执行DO循环中的语句。DO WHILE语句在每次DO循环迭代开始前检查条件。
2 SAS数组
如果需要对许多变量做相同的操作,虽然可以通过写一系列赋值语句来实现,使用数组可以简化程序代码。
数组是一组以特殊顺序排列并由数组名标识的SAS变量。只要一组变量名都是同一类型,例如都是数值型或字符型,就可以为该组变量定 义一个数组。这些变量可以是数据集中已经存在的,也可以是要创建的 新变量。数组仅仅在当前DATA步中存在,在同一DATA步中,数组按 名字区分。SAS数组不是一种数据结构,只是临时标识一组变量较方便 的方法,在这点上SAS数组不同于其他编程语言中的数组。
1.数组定义及引用
在DATA步中使用ARRAY语句定义数组。定义数组的基本形式如 下:
- ARRAY 数组名 {下标} <$> <长度> <数组元素> <(初始值列表)>;
其中:
- ·数组名是指定给数组的名称。该数组名在同一DATA步中不能与任何其他变量名或关键字重名。其命名需遵循SAS变量的命名规范(不超 过32个字符,以字母或下划线开始,可包含字母、数字和下划线)。
- ·下标可以有多种形式,通常为指定数组元素个数、上下边界或*。*表示通过计算数组元素个数确定数组下标。
- ·$指定数组中的元素是字符元素。如果数组元素是数字元素或先前 已经定义的字符元素,则不需要使用$。
- ·长度指定先前未指定长度的元素的长度。
- ·数组元素指定组成数组的元素名称。
- ·初始值列表给出数组中对应元素的初始值,以空格隔开。定义数组时的括号可以是()、{}或[]。定义数组时的下标形式指定了数组维度、各个维度的下边界和上边界。
还可以通过不同格式的下标指定多维数组,多个维度之间用逗号(,)分隔,同一个维度内的上下边界使用冒号(:)分隔,如表3.8所示。
数组元素可以是数值型或字符型,并且可以以任何顺序列出,其个数必须等于括号{}中给出的下标值。
数组元素可以是已经存在的变量或不存在的变量,当数组元素是不存在的变量时,SAS会创建新变量。除了列出变量外,变量可以是关键 字_NUMERIC_、_CHARACTER_或_ALL_。
还可使用关键字_TEMPORARY_来创建临时数据元素。临时数据元素不会出现在输出数据集中,并且其值总是自动保持,而不会在DATA 步的每次迭代开始时自动设置为缺失值。临时数组元素仅用于计算,如果要保留计算结果,需要将结果赋值给其他变量。使用临时数组元素的 好处是可以提高性能。
使用数组名引用变量时,要给出数组名和该变量的下标。例如,使 用如下ARRAY语句定义变量STORE,共4个元素,分别为变量Macys、Penneys、Sears和Target。
- array Store {} Macys Penneys Sears Target;
使用数组名引用变量时,STORE{1}是变量Macys,STORE{2}是Penneys,STORE{3}是Sears,STORE{4}是Target。 如果定义数组时指定了上下边界,例如:
- array Month {:} April May June;
则Month{4}是变量April,Month{5}是变量May,Month{6}是变量June。
这样就可以在循环中通过改变数组下标来操作每个数组元素对应的 变量,所以数组经常在DO组中使用。
2.数组函数
SAS提供了DIM、HBOUND和LBOUND函数返回数组中指定维度 的元素个数、上边界和下边界。
DIM函数返回一维数组中的元素个数或多维数组中指定维度中的元素个数。其形式如下:
- DIM<n>(数组名)或DIM(数组名, 维度)
HBOUND函数返回一维数组的上边界或多维数组中指定维度的上 边界。其形式如下:
- HBOUND<n>(数组名)或HBOUND(数组名, 维度)
LBOUND函数返回一维数组的下边界或多维数组中指定维度的下边 界。其形式如下:
- LBOUND<n>(数组名)或LBOUND(数组名, 维度)
其中:
- ·n指定维度的整型常量。如果未指定n值,则返回数组的第一维的结果。
- ·数组名指定在同一DATA步中先前定义的数组名称。
- ·维度是指定维度的数字常量、数字变量或数字表达式。
3.DO循环中引用数组元素 将数组与迭代DO语句结合使用,在对用数组所表示的变量进行处理时会变得简单。其基本形式如下:
- DO 索引变量= TO 数组元素个数;
- … SAS语句…
- END;
使用数据集saslib.revenue_quarter制定明年的销 售计划,预期各季度的销售额为今年的150%。
代码如下:
- data saslib.revenue_2014;
- set saslib.revenue_quarter;
- array Quarter {} Rev_Q1-Rev_Q4;
- do i= to ;
- Quarter{i} = Quarter{i}*1.5;
- end;
- drop i;
- run;
其中:
- ·ARRAY语句定义了数组Quarter,其元素个数为4。因为变量 Rev_Q1到Rev_Q4在输入数据集中存在,所以该数组只是引用存在的变 量Rev_Q1到Rev_Q4,并不创建新变量。这里数组元素使用了简化的表 达方式。
- ·在DATA步的每次迭代中,通过在DO循环中引用Quarter{1}到 Quarter{4}来分别操作变量Rev_Q1到Rev_Q4,将销售额在现有销售数据 的基础上增加50%。
数据集saslib.revenue_2014在VIEWTABLE窗口打开如图所示。
SAS 循环与数组的更多相关文章
- *使用while循环遍历数组创建索引和自增索引值
package com.chongrui.test;/* *使用while循环遍历数组 * * * */public class test { public static void main ...
- 关于for循环删除数组内容出现的问题
昨天用for循环进行数组去重的时候出现的问题, 首先,用双重for循环把前一个和所有后面的元素进行比较,如果相等则删除. 但是,如果数组里面有三个以上连续相等的元素的时候,就会出现问题. var ar ...
- JavaScript 中 for in 循环和数组的问题
本文由 伯乐在线 - ElvisKang 翻译,进林 校稿.未经许可,禁止转载!英文出处:adripofjavascript.com.欢迎加入翻译小组. JavaScript的for…in循环用于迭代 ...
- JavaScript基础精华03(String对象,Array对象,循环遍历数组,JS中的Dictionary,Array的简化声明)
String对象(*) length属性:获取字符串的字符个数.(无论中文字符还是英文字符都算1个字符.) charAt(index)方法:获取指定索引位置的字符.(索引从0开始) indexOf(‘ ...
- swift基本用法-for循环遍历,遍历字典,循环生成数组
// Playground - noun: a place where people can play import UIKit //--------------------------------- ...
- PHP(方法 函数 循环 和 数组 查找)
循环 和 数组 查找 顺序查找 二分法查找 冒泡排序 方法 函数 定义:一堆代码的集合叫做函数(满足条件下“一堆”) 语法,定义,调用,参数列表(形参,实参),返回值 两种方法: function 方 ...
- js循环遍历数组
一维数组的遍历 <script> //循环遍历数组 var animals = ["cat",'dog','human','whale','seal']; var an ...
- for循环遍历数组(数组1)
package com.mon10.day24; import java.util.Scanner; /** * 类说明 :计算学生的总成绩和平均分 * @author 作者 : chenyanlon ...
- LeetCode 81 Search in Rotated Sorted Array II(循环有序数组中的查找问题)
题目链接:https://leetcode.com/problems/search-in-rotated-sorted-array-ii/#/description 姊妹篇:http://www. ...
随机推荐
- python中线程2
cpython中的GIL和pool GIL锁(全局解释器锁) 1.what? GIL是全局解释器锁,和普通锁加在数据上不同的是:GIL加在加在解释器上,是为了防止多个线程在同一时间执行python字节 ...
- MyEclipse Web项目部署失败:Deployment failure on Tomcat 7.x.Could not copy all resources to XXX.
在做第一个MyEclipse web项目时,总是部署失败: Deployment failure on Tomcat 7.x.Could not copy all resources to XXX.I ...
- Git自学笔记
Git是什么? Git是目前世界上最先进的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目. Git与SVN的区别有哪些? ① Git是分布式的,SVN不是.这是Git和其它非分布式版本控制系 ...
- java二分法搜索
二分法就是要将数据每次都分成两份然后再去找到你想要的数据 在二分法查找时要求传入的数据必须已经有序,假设现在为升序,然后每次将所寻找的值与中间值(数组左边界+(右边界-左边界)/2)作比较,大了则去寻 ...
- python 列表去重的几种方法
1 a = [,,,,,,,,,,] a1 = [] for i in a: if i not a1: a1.append(i) else: continue 2 a = [,,,,,,,,,] a1 ...
- winform UI 设计方法
这里主要提供了一种设计思路,你可以将成套的UI图像添加或替换到本程序中.在设计过程中,还存在许多疏漏,懒得仔细修改了,在使用过程中自行修改添加.这里的函数基本上都可以单独使用,需要哪个将cs文件加入到 ...
- adduser与useradd的区别
问题:使用 useradd 创建用户,发现 /home 目录下没有自动创建关于用户的目录.所以做了一番调查研究 useradd是一个linux命令,但是它提供了很多参数在用户使用的时候根据自己的需要进 ...
- Mapnik 3.0.20编译安装
1. 确定epel安装 yum install -y epel-release 2. 按照<CentOS7.2部署node-mapnik>一文中的步骤,手动安装 gcc-6.2.0 和 b ...
- optional的使用
:first-child { margin-top: 0px; } .markdown-preview:not([data-use-github-style]) h1, .markdown-previ ...
- python基础 (序列化,os,sys,random,hashlib)
1.序列化 定义: JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.简单地说,JSON 可以将 JavaScript 对象中表示的一组数据转换为字符串,然 ...