06-SAS 数据集的整理

SAS 数据集的基本整理与变换

作者

Simon Zhou

发布于

2025年5月26日

%load_ext saspy.sas_magic

1 浏览与修改数据集

使用软件窗口的 Table editor/browse(edit) 菜单选项进行数据集的浏览与修改。

2 产生新变量

2.1 直接生成新变量

在数据集中可以通过SAS 提供的运算符和函数直接产生新变量,如将 程序 2-1 中生存时间的单位由天改为年,可产生一个新变量 surt_y,

该变量的值等于变量 surt 除以 365.25,所以变量 surl_y 将表示单位为年的生存时间。可用如下程序:

/*程序2-9*/
/*产生新变量,改天为年*/
data prg2_6;
    infile 'C:\Document\SASData\syz.txt';
    input no sex $ age blood $ surt;
    surt_y = surt/365.25;
proc print data = prg2_6;
run;

2.2 if-then/else 语句生成变量

通过 if-then/else 语句也可以产生新变量。

仍用 程序 2-1 的数据,程序 2-11 表示将产生一个新的分组变量,变量名为 group ,其中变量值为 1 表示年龄 >40 岁的患者,变量值为 2 表示年龄 ≤40 岁的患者。

/*程序2-1`*/
/*使用if-then/else来产生新变量*/
data prg2_7;
    infile 'C:\Document\SASData\syz.txt';
    input no sex $ age blood $ surt; 
    if age>40 then group =1;
    else group = 2;
datalines;
......
;
run;

2.3 多条件下的 if-then 语句

如果满足的条件超过两个,可以使用 andor 语句来控制。and 语句表示同时满足几个条件,就执行 then 后面的语句; or 表示只需满足几个 条件中的一个条件,就执行 then 后面的语句。程序 2-12 表示将年龄 >40 岁的男性患者归为一组, 将年龄 ≤40 岁的男性患者归为另一组。

/*程序2-12*/
/*满足条件超过2个,可以使用and和or语句来控制*/
/*由于sex为字符型变量,所以在表示其变量值时,需要在变量值两侧加上引号,单引号、双引号均可*/
data prg2_8;
    infile 'C:\Document\SASData\syz.txt';
    input no sex $ age blood $ surt; 
    if sex = 'M' and age>40 then group =1;
    if sex = 'M' and age<=40 then group =2;
datalines;
......
;
run;

3 数据集的排序

将数据集中的所有观测按照一个或几个变 量的数值大小进行排序,可以使用 sort 过程。sort过程的语法结构如下:

proc sort options;
by [descending] variable-list;
run;

语句中的 options 是表示 sort 过程可以使用的某些选项,其中一些常用的选项如下:

  • data = 数据集: 表示 sort 过程将对哪个数据集进行排序,如缺省该项,则使用最新创建的数据集;
  • out = 数据集: 表示 sort 过程将排好序的数据输出到哪个数据集,如缺省该项,则将数据存放原来的数据集中,将原来数据集中的内容替换掉。
  • by 语句: 表示 sort 过程将按照哪个变量对数据集进行排序。
    • descending: by语句 中的选项,如果选择该项,则表示按变量值的下降次序排序,如缺省该项,则按上升次序排序。该选项只决定紧随其后的一个变量的排序次序。
  • variable-list: 用来排序的变量名。当有多个变量时,sort 过程首先按 by 语句的第一个变量的次序重新排列观测,然后在此基础上,按第二变量 的次序重新排列观测,即当第一个变量的观测值相同时,再按第二变量的观测值排序,依次类推。 sort 过程对相同by变量值的那些观测保持原来的相对顺序.
  • 如果变量是数值型, sort 过程则按数值的大小排序;如果变量是字符型的,sort 过程先按每个变量值的第一个字母排序,如果第一个字母相同,则按第二个字母排序,依此类推。
%%SAS
/*程序2-12*/
data prg2_1;
    input no sex $ age blood $ surt;
datalines;
1 M 41 A 368
2 M 26 B 745
3 F 35 B 401
4 M 37 AB 552
5 F 37 A 478
6 F 39 O 628
7 M 28 O 549
8 M 31 B 128
9 M 43 AB 463
10 M 29 A 512
;
run;

proc sort data = prg2_1 out = prg2_9;
    by descending sex surt;
run;

proc print data =prg2_9;
    title '程序2-12';
run;
SAS 输出

程序2-12

观测 no sex age blood surt
1 8 M 31 B 128
2 1 M 41 A 368
3 9 M 43 AB 463
4 10 M 29 A 512
5 7 M 28 O 549
6 4 M 37 AB 552
7 2 M 26 B 745
8 3 F 35 B 401
9 5 F 37 A 478
10 6 F 39 O 628

4 数据集的连接

数据集的连接是把几个数据集中的数据纵向相加,组成一个新的数据集,新数据集中的观测数量是原来几个数据集中观测的总和。set 语句可以完成数据集的连接,语法结构为:

data newname;
set name1 name2:
run;

其中 newname 是新数据集的名称, namelname2 是要连接的原数据集的名称,如果有多个数据集,则可以用逗号分隔开。 如果要连接的数据集的变量名相同,则新数据集中的变量名与原数据集中的变量名相同,如果原数据集中的变量名不同,则新数据集中的变量名为原数据集中所有变量名的并集;其中原数据集中没有的变量,在新数据集中将表示为缺省值.

5 数据集的合并

数据集的合并是将几个数据集中的观测横向合并成一个新的数据集,合并数据集可使用 merge 语句, merge 语句的语法结构为:

data newname;
merge name1 name2.
by keyvar;
run;

data 步中的 newname 为新数据集的名称, name1name2 为原数据集的名称,还可以有多个数据集名,彼此之间用空格分隔,合并前需对原数据集按 keyvar 排序。

by 语句表示可以根据 keyvar 所规定的关键变量进行合并,原数据集必须都有 keyvar 变量。

如果没有 by 语句,合并时将一个数据集的第一个观测值和另一个数据集中第一个观测值合并成新数据集中的第一个观测值,第二个观测值和另一个数据集中的第二个观测值合并成新数据集的第二观测值,依次类推。

%%SAS
/*程序2-13*/
/*数据的合并,merge语句的使用*/
/*创建两个数据集*/
data prg_a;
    input no sex $ age;
datalines;
1 M 41
2 M 26
3 F 35
4 M 37
5 F 37
6 F 39
7 M 28
8 M 31
9 M 43
10 M 29
;
proc print data = prg_a;
    title '程序2-13';
run;

data prg_b;
    input num blood $ surt;
datalines;
41 A 368
26 B 745
35 B 401
37 AB 552
37 A 478
39 O 628
28 O 549
31 B 128
43 AB 463
29 A 512
;
proc print data = prg_b;
    title '程序2-14';
run;

/*程序2-15*/
/*对两个数据集进行合并*/
data prg2_11;
    merge prg_a prg_b;
run;
proc print;
    title '程序2-15';
run;
SAS 输出

程序2-13

观测 no sex age
1 1 M 41
2 2 M 26
3 3 F 35
4 4 M 37
5 5 F 37
6 6 F 39
7 7 M 28
8 8 M 31
9 9 M 43
10 10 M 29

程序2-14

观测 num blood surt
1 41 A 368
2 26 B 745
3 35 B 401
4 37 AB 552
5 37 A 478
6 39 O 628
7 28 O 549
8 31 B 128
9 43 AB 463
10 29 A 512

程序2-15

观测 no sex age num blood surt
1 1 M 41 41 A 368
2 2 M 26 26 B 745
3 3 F 35 35 B 401
4 4 M 37 37 AB 552
5 5 F 37 37 A 478
6 6 F 39 39 O 628
7 7 M 28 28 O 549
8 8 M 31 31 B 128
9 9 M 43 43 AB 463
10 10 M 29 29 A 512

5.1 含有缺失值的合并

%%SAS
/*程序2-16*/
/*缺失值*/
data prg_c;
    input num blood $ surt;
datalines;
41 A 368
26 B 745
35 B 401
37 AB 552
37 A 478
39 O 628
28 O 549
;
run;

data prg2_12;
    merge prg_a prg_c;
proc print data = prg2_12;
    title '程序2-16';
run;
SAS 输出

程序2-16

观测 no sex age num blood surt
1 1 M 41 41 A 368
2 2 M 26 26 B 745
3 3 F 35 35 B 401
4 4 M 37 37 AB 552
5 5 F 37 37 A 478
6 6 F 39 39 O 628
7 7 M 28 28 O 549
8 8 M 31 .   .
9 9 M 43 .   .
10 10 M 29 .   .

5.2 by 语句

by 语句可以对数据集进行分组,并对每个组进行处理。

%%SAS
/*程序2-17*/
/*使用by语句来进行排序在合并*/
data prg_f;
    input no sex $ age;
datalines;
1 M 41
2 M 26
4 M 37
5 F 37
7 M 28
8 M 31
;
run;
data prg_g;
    input no blood $ surt;
datalines;
2 A 368
3 B 745
6 AB 552
8 A 478
9 O 549
;
run;

proc sort data = prg_f;
    by no;
run;
proc sort data = prg_g;
    by no;
run;
data prg2_14;
    merge prg_f prg_g;
    by no;
run;
proc print;
    title '程序2-17';
run;
SAS 输出

程序2-17

观测 no sex age blood surt
1 1 M 41   .
2 2 M 26 A 368
3 3   . B 745
4 4 M 37   .
5 5 F 37   .
6 6   . AB 552
7 7 M 28   .
8 8 M 31 A 478
9 9   . O 549

6 数据集的求秩

利用 rank 过程可以对数据集中的一个或者多个变量进行求秩。rank 过程把未缺失的数值从最小值到最大值排列,对最小值赋予秩1,对第二小值赋 予秩 2,等等,一直赋予秩n,即未缺失的观测个数出现数值相同的观测值时,其秩可以取两者的平均秩或最高秩或最低秩。

rank 过程的语法结构如下:

proc rank options;
    var variable-list:
    ranks variable-list;
run;

6.1 语句中的 options

语句中的 options 是表示 rank 过程可以使用的某些选项,其中一些常用的选项如下: - data = 数据集: 表示 rank 过程将对哪个数据集进行排秩,如缺省该项,则使用最新创建的数据集。 - out = 数据集: 表示 rank 过程将排好秩的数据输出到哪个数据集,如缺省该项,则将数据存放原来的数据集中,将原来数据集中的内容替换掉。 - var 语句: 表示 rank 过程将对哪个变量进行排秩,如果有多个变量,则用逗号分隔开。 - descending: 求秩顺序选项,如果选择该项,则表示按变量值的下降次序求秩,如缺省该项,则按上升次序求秩。 - ties=mean|high|low:表示对数值相同的观测值如何取秩。ties 等于 mean 表示数值相同的观测值取平均秩,等于 high 表示取相应秩中的最大值,等于 low 表示取相应秩中的最小值。 ### var语句

该语句表示 rank 过程对哪个变量求秩,对多个变量求秩时,变量名以空格分开。如果省略 var 语句,则对数据集中所有数值变量计算秩。

6.2 ranks语句

如果希望在输出数据集中除了秩变量外还包括原始变量,使用 ranks 语句对求秩变量分配求秩后的名称。命名的次序和 var 语句变量列表中的次序相对应。如果省略 ranks 语句,则输出数据集中只有求秩后的结果而没有原始变量。ranks 语句必须与 var 语句同时使用。

程序 2-18 表示将数据集 prg2_1 中的 agesurt 变量按从小到大的顺序求秩,相应的秩变量分别为 age_ranksurt_rank,将结果输出到数据集 prg2_14 中,并将求秩后的结果显示到输出窗口中:

%%SAS
/*程序2-18*/
/*数据集的求秩过程*/
proc rank data = prg2_1 out = prg2_15 ties = mean;
    var age surt;
    ranks age_rank surt_rank;
run;
proc print;
    title '程序2-18';
run;
SAS 输出

程序2-18

观测 no sex age blood surt age_rank surt_rank
1 1 M 41 A 368 9.0 2
2 2 M 26 B 745 1.0 10
3 3 F 35 B 401 5.0 3
4 4 M 37 AB 552 6.5 8
5 5 F 37 A 478 6.5 5
6 6 F 39 O 628 8.0 9
7 7 M 28 O 549 2.0 7
8 8 M 31 B 128 4.0 1
9 9 M 43 AB 463 10.0 4
10 10 M 29 A 512 3.0 6

7 数据集的转置过程

对数据集进行转置,即行变成列,列变成行可以使用 transpose 过程。transpose 过程的基本语法结构如下:

proc transpose options;
    var variable-list:
    id variable;
    by variable-list;
run;

7.1 语句中的 options

是表示 transpose 过程可以使用的某些选项,其中一些常用的选项如下:

  • data = 数据集: 表示 transpose 过程将对哪个数据集进行转置,如缺省该项,则使用最新创建的数据集。
  • out = 数据集: 表示 transpose 过程将转置后的数据输出到哪个数据集,如缺省该项,则将数据存放于名称为 datan 的数据集中( datan 中的 n 可取1,2,3…n).

7.2 var语句

该语句表示 transpose 过程对哪个变量进行转置,如果有多个变量,则用逗号分隔开。如果省略 var 语句,则对数据集中所有数值变量进行转置。

7.3 id语句

该语句表示 transpose 过程将哪个变量的值作为转置后数据集中的列名,如果省略 id 语句,则转置后的数据集中的列名为 col1, col2, col3 等。

id 变量的值在输入数据集中只能出现一次;或者使用 by 语句,则在 by 组中只能出现一次。id 变量缺失的观测将从输出数据集中删去。

7.4 by语句

该语句表示 transpose 过程将对哪个变量进行分组转置,如果有多个变量,则用逗号分隔开。如果省略 by 语句,则对整个数据集进行转置。

使用by语句可以对每个 by 组进行转置, by 变量包含在输出数据集中但没有被转置。使用 by 语句,要求数据集按照 by 语句后面的变量进行排序

%%SAS
/*程序2-19*/
/*数据集的转置过程*/
proc transpose data = prg2_1 out = prg2_16;
    var sex age surt;
    id no;
run;
proc print;
    title '程序2-19';
run;
SAS 输出

程序2-19

观测 _NAME_ 1 2 3 4 5 6 7 8 9 10
1 sex M M F M F F M M M M
2 age 41 26 35 37 37 39 28 31 43 29
3 surt 368 745 401 552 478 628 549 128 463 512

8 数据的输出

SAS还可以将SAS数据集转换成其他格式的数据文件,如 *.dbf、*.xls、*.csv、*.txt 等,供其他软件使用。 “File(F)” 菜单中 “Export Data(E)” 选项可以完成这项功能,