SAS的基本使用介绍2(变量的输入输出格式)

前言

有关SAS的基础使用可以回看上一篇
SAS的基本使用介绍1(数据集建立与输入输出格式)
本文将继续介绍SAS基本使用

自定义格式

SAS的灵活之处在于可自定义输入输出
例如:在输入性别时,输入1,2,通过自定义格式SAS可以自动读成男和女

proc format;
invalue<$> 格式名 变量值或范围1=输入格式1 变量值或范围2=输入格式2......;
value<$> 格式名 变量值或范围1=输出格式1 变量值或范围2=输出格式2......;
picture 模板名 <数值范围>;

value中“输入格式1”是字符型要$,
invalue中“变量值或者范围”是字符型要 $符号----由硬盘里的存储类型决定

invalue $ sex 1="男" 2="女"
*创建输入格式名sex,输出1时,自动变为="男"
invalue grade "a"-"g"=1 other=2
value age low-<40=30 40-<50=40 50-high=50;
value score low-59="不及格" other="及格"
proc format;
invalue $abc 1="男" 2="女";
data e;
input id sex $abc.;
cards;
11 1
20 2
26 2
37 1
;
proc print;
run;
proc format;
invalue $ fage low-<45="青年" 45-high="中年";
data e2;
input id age: $fage.;
cards;
1 37
2 29
3 58
;
proc print;
run;

自定义格式名后面要加.

总结:
值和格式可以是不同类型,可以把字符设置为数值,反之亦然;
字符和数值一样,可以用“-”连接起来作为一个范围;
可以用other表示其他情况:可以用“<”和“>”等符号制定范围,可以用“ same ”来保持原值。

picture
format语句定义的是输出格式,定义的是我们要显示的值,而picture语句不是定义值,而是定义一种显示的样式,例如,把数据中的profit显示为“$”的形式,把prop显示为“%”的格式

proc format;
picture pft low-high="0,000,000"(prefix="¥");
picture pro low-high="00.99%";
run;
data profit;
input profit prop;
format profit pft. prop pro.;
cards;
36780 15.90
902463 30.19
;
proc print;
run;
  • low-high的范围就是从最低值到最高值
  • pro的定义有0和9,0的作用是自动舍去数字前面的0,而1-9不会舍去;
    例如:0.72指定“00.00%”那会显示成“72%”,“99.99%”会显示成 00.72%, “09.99%”则显示0.72%
  • 注意:如果36780变成000036780不影响因为自动舍去,但如果36780–>36780000,输出变成6,780,000没有¥ 不妨把9理解成占位符用来表示结果有几位

如何产生新变量

1. 利用表达式或函数直接产生新变量

基本格式:变量名=表达式或函数;
变量名可以是新变量,也可以是已有变量,若为已有变量,表示用新值代替原有值

data e1;
input wt ht;
bmi=wt/(ht/100)**2;
rbmi=sqrt(bmi);
obesity=(bmi>=28);
city="西安";
cards;
60 172
55 165
88 170
;
proc print;
run;

我们不难发现在SAS中新变量是不需要声明的,并且他们都会成为观测值显示在输出中
注意:这个input 后面的变量值是用户在cards后面输入的值,SAS也就凭此分组

2. if-then语句产生新变量

使用if-then语句产生新变量

if 表达式 then 新变量=  ;
else 新变量= ;
data lx;
input id lx$;
lx1=lx in ("显著","有效","治愈");
if lx in ("显著","有效","治愈") then lx2="有效";
else lx2="无效";
cards;
1 显著
2 有效
3 无效
4 治愈
;
proc print;
run;

逻辑运算产生的表达式的新变量值只能是0或1,if-then语句产生的新变量值更加丰富

3. 利用retain语句和累加语句产生新变量

了解SAS读取数据的特点

SAS在读取数据时是无记忆的,每次读完一条观测返回到data语句时,会忘掉刚才读取的值

data e3;
a=0;
a=a+1;
input wt ht;
cards;
60 172
59 168
75 180
;
proc print;
run;

SAS在每次返回data语句进行新一轮的读取过程中会忘记a的值重新读取

retain语句使用

它的作用是生成一个变量,指定它的初始值,并保留该值每次计算的结果。如果没有初始值,默认初始值为缺失值。
retain语句可以指定一个或多个变量

retain 变量<初始值>
retain a 29;
retain year 2021 tatal 0; 

累加语句

累加语句的作用是产生一个累加的变量值。它形式上和前面学习的用表达式产生变量差不多,但是去掉了左面的“变量=”,直接写右面的表达式。
书写更加简单,且兼具retain语句的功能。累加语句中的变量如果在前面没有出现默认为0

变量+表达式;
year+1; *默认yaer=0,year+1产生的结果就是year=1
total+amount

比较下面三个程序

data e41;
count=0;
count=count+1;
input time;
cards;
25
36
29
;
proc print;
run;
data e42;
retain count 0;
count=count+1;
input time;
cards;
25
36
49
;
proc print;
run;
data e43;
count+1;
input time;
cards;
25
36
49
;
proc print;
run;

看下面一个例子:相当于定下了初始值同时使用累加,简化了语句

data e5;
input amount;
retain year 2021;
year+1;
total+amount;
cards;
100
200
300
;
proc print;
run;

4.利用do循环语句产生新变量

初始值、最终值、增加值可以是数值,也可以是字符
注意:SAS可以指定字符作为循环,增量相同的情况下,使用方便。若没有规律,就只能用逗号隔开挨个写

do 变量=初始值 to 最终值<by 增加值>;
SAS语句;
end;

do i=1 to 100;
do i=1 to 100 by 2;
do i=1,2,5,8;
do i="JAN","FEB","MAR";
data e61;
input count time;
cards;
1 23
2 29
3 49
4 64
5 87
;
proc print;
run;

使用do循环

data e62;
do count=1 to 5;
input time;
output;
end;
cards;
23
29
49
64
87
;
proc print;
run;

1.如果不加上output,count只会输出一个观测值6,因为前面的数没有给SAS下指令
2.end不加,会导致SAS找不到循环结束的标志,给不出结果

指定新变量的类型和长度

length的使用:数值型 3~ 8,字符型1~32767
input只能指定原有变量的长度与类型

length 变量1 <$> 长度1 变量2 <$> 长度2 ...; 
data lx;
input id lx$;
length lx1 $16.;
if lx="无效" then lx1="无效";
else lx1="显著+有效+治愈";
cards;
1 显著
2 有效
3 无效
4 治愈
;
proc print;
run;

SAS规定:新字符变量的长度是由第一个遇见的值的长度决定的,而且字符变量一旦产生,长度就无法改变
注意:length需要在新变量产生前就设置好

@符号在输入方式中的应用

  1. @@ 能让 SAS 系统向右读。
  2. @ 和 @@ 都是向右读,@ 只能在有两个 input 语句的 data 中才能使用。
  3. @ 在两个 input 语句中,一般用于第一个 input 语句,使用的效果是:若第一个 input 语句一次要读取 n 个变量的数据,先将第一行的前 n 个数据作为第一个 input 的数据,第一行剩下的数据就交给第二个 input 来读取,第二个 input 读取完后,再重复此过程于第二句。(配合例子)

原代码

data score;
input gender$ id score;
cards;
M 1 86
M 2 90
M 3 83
M 4 79
F 1 85
F 2 93
F 3 90
;
proc print;
run;

使用 @ 双 input 语句代码:

date score;
input gender$ n@;
do id=1 to n;
input score@@;
output;
end;
cards;
M 4 86 90 83 79
F 3 85 93 90
;
proc print;
run;

SAS函数的应用

1. 数值计算相关函数

在这里插入图片描述
在这里插入图片描述

2. 字符有关函数

2.1计算变量的长度

Length(变量):计算变量长度,对缺失值返回1
Lengthn(变量):计算变量长度,对缺失值返回0

多为实现其他目的的中间过程

2.2提取变量中的字符

如果要对一个变量的所有值进行同样的操作,而这个变量的观测值长度又不同,需要先判断变量长度,然后设置不同的条件

data e3;
input iden: $18.;
if length(iden)=18 then gen=substrn(iden,17,1);
else gen=substrn(iden,15,1);
if mod(gen,2)=1 then gender=" 男";
else gender="女";
cards;
36053319720613591x
360533851009226
;
proc print;
run;

data e3;
input iden: $18.;

if length(iden)=18 then year=substrn(iden,7,4);
else year=substrn(iden,7,2)+1900;

if length(iden)=18 then month=substrn(iden,11,2);
else month=substrn(iden,9,2);

if length(iden)=18 then day=substrn(iden,13,2);
else day=substrn(iden,11,2);

cards;
36053319720613591x
360533851009226
;
proc print;
run;

2.3 查找变量中的字符

find(变量,查找内容<, "i"> <, 起始位置>)
findc(变量,查找内容<, "i"> <, 起始位置>)

find 多个字符的查找
findc找到字符中的任意一个就算找到了

例如:find:寻找“SAS”这个整体
findc:只要找到S或A任意一个字母都认为找到了

加上"i",表示忽略字符的大小写

data e4;
input book: & $50.;
sas=find(book, "sas","i");
if sas>0 then class="sas书";
else class="其他书";
cards;
The little SAS book
概率论
SAS编程技术教程
高等数学
SAS应用分析
SPSS数据分析
;
proc print;
run;

查找提取函数

anyalpha(变量<,起始位置>):查找变量中任意的字母,并返回第一个字母位置
anydigit(变量<,起始位置>):查找变量中任意的数字,并返回第一个数字位置
anyalnum(变量<,起始位置>):查找变量中任意的数字或字母,并返回第一个位置
data e5;
input type$@@;
alpha=anyalpha(type);
digit=anydigit(type);
xh=substrn(type,alpha,digit-alpha);
bh=substrn(type,digit,length(type)-digit+1);
cards;
TP340 KS320 B3510 C560 H430
;
proc print;
run;

2.4替换变量中的字符

tranwrd(变量,查找值,替代值)
data lx;
input id lx$;
lx1=tranwrd(lx,"显著","有效");
lx1=tranwrd(lx1,"治愈","有效");
cards;
1 显著
2 有效
3 无效
4 治愈
;
proc print;
run;

该函数每次只能替换一个

2.5去除变量中的字符

compress(变量<,欲去除的字符><,"修饰符">)

常见的修饰符:
a,去除变量中的所有字母
d,去除变量中的所有数字
s,去除变量中的所有空格
i,忽略大小写
k,保留“欲去除的字符”,去掉其他字符

data e7;
input type$@@;
xh=compress(type, ,"d");
bh=compress(type, ,"a");
cards;
TP340 KS320 B3510 C560 H430
;
proc print;
run;

使用该函数统一格式

data e8;
input phone:&$16. @@;
phone1= compress(phone,"(-)");
phone2=compress(phone, ,"kd");
cards;
(029)8889080
029-7698779
029 8908098
;
proc print;
run;

2.6 变量的合并

SAS中可以使用“||”连接变量

cats(变量1,变量2,......);
*删掉中间空格
catx("分隔符",变量1,变量2);
*中间用分隔符隔开

2.7清点变量中某字符的个数

data e10;
input comment&:$60.;
beauty=count(comment,"清晰");
cards;
发货快,收到完好,印刷清晰,不错
需要就值得买,纸张好,印刷清晰
内容详实细致,很有见地,印刷精美,纸质很好,值得购买
字体清晰,印刷质量好!
书籍到货完整,没有破损,纸张质量很好,印刷清楚。学习中......
包装严实,印刷清晰
非常棒的书,印刷清晰,得仔细阅读
很一般般
赞一个
物美价廉
;
proc print;
run;

2.8查找变量的缺失值

SAS中用“.”表示缺失值,可以使用if语句查找,但missing更高效

missing(变量);
判断是否为缺失值,是返回1,否则返回0
data e12;
input id sex$ age@@;
msex=missing(sex);
mage=missing(age);
cards;
1 f 39 2 m 70 3 f . 4 . 53
;
proc print;
run;

3.与日期和时间相关的函数

通常计算前后两个日期的差值,先使用变量合并函数,合并成日期变量,再做减法

data date;
input year1$ month1$ day1$ year2$ month2$ day2$;
date1=catx("/",year1,month1,day1);
date2=catx("/",year2,month2,day2);
dif=date2-date1;
cards;
2019 05 21 2021 03 12
2019 01 11 2020 11 15
2019 07 23 2021 07 26
;
proc print;
run;

SAS时间本质是数值型的,catx函数合并是数值型的,没办法运算
cats合并后求差,完全当成数字处理,不正确
需要专门的函数处理

可以使用input进行变量转换,主要用于将字符型转换成数值型,put函数的主要作用是把数值型转化成字符型

data date;
input year1$ month1$ day1$ year2$ month2$ day2$;
date1=catx("/",year1,month1,day1);
date2=catx("/",year2,month2,day2);
d1=input(date1,yymmdd10.);
d2=input(date2,yymmdd10.);
format d1 d2 yymmdd8.;
dif=d2-d1;
cards;
2019 05 21 2021 03 12
2019 01 11 2020 11 15
2019 07 23 2021 07 26
;
proc print;
run;

3.1日期的合并与差值

* 合并日期的函数
mdy(月,日,年)

* 计算差值的函数
* * 以年为单位的差值
yrdif(开始日期,结束日期,"计算依据")
* 以日为单位的差值
datdif(开始日期,结束日期,"计算依据")

计算依据
通常是actual
ACT/365:不管是否闰年,按365天计算。

data date;
input year1$ month1$ day1$ year2$ month2$ day2$;
date1=mdy(month1,day1,year1);
date2=mdy(month2,day2,year2);
format date1 date2 yymmdd10.;
ydif=yrdif(date1,date2,"actual");
ddif=datdif(date1,date2,"actual");
cards;
2019 05 21 2021 03 12
2019 01 11 2020 11 15
2019 07 23 2021 07 26
;
proc print;
run;

3.2日期的提取

在这里插入图片描述

带有时间的日期变量比较复杂,它的输入和输出格式和单纯的日期变量不同
输入格式:
datetimew.格式 如:26JUN09:13:25:26;
ymddttmw.格式 如:2009/6/26/:13:25:26
输出格式:
datatimew.格式

如果只有时间,没有日期,输入和输出格式可以写成timew.格式

4.与概率和分布有关的函数

在这里插入图片描述

5.dif和lag函数

lag:返回变量的滞后值
dif:返回当前记录和前一个记录的差值

data e17;
input year profit@@;
plag=lag(profit);
pdif=dif(profit);
pratio=pdif/plag;
cards;
2008 989 2009 1002 2010 1023 2011 1022 2012 1065 2013 1112
;
proc print;
run;

猜你喜欢

转载自blog.csdn.net/m0_52739647/article/details/120495117