SAS Training 003 - R reshape | SAS transpose
在 R 中,我们称长宽数据的转置为 reshape,相信很多小伙伴都非常熟悉;而在 SAS 中,对应的操作为 proc transpose。虽然我们也可以利用 data 步来完成(极其地 tedious),但是远没有 proc transpose 来得简洁明了。我们这里重点聊 SAS 的 transpose,R 中的操作我们留到 R Training 的推送。
数据结构
wide data
t 检验等等,这么一说,是不是感觉知识都回来了,不再局限于 wide data 这个名头了?
long data / narrow data
是的,wide data 数据一般一个观测只有一行数据,每个变量有一列。但是,我们也接触过这样的数据:临床试验中,我们对受试者进行有规律的访视,每个 subject 每次 visit,我们都会记录生成一行数据,如此下来,结束随访时,每个 subject 会拥有多行数据,且每行里有 cell 会记录该行 visit 的日期,我们直接上图:

这样的话,对于 long data 的理解就清晰多了,其对应的 wide data 如下:

显然,我们经常接触下面的 wide 格式,如果我们想比较两次 wight 之间变化关系,应用这种格式就方便多了。但是,对于上面的 long 格式呢,我们如果想转成 wide,怎么操作?或者由 wide 转为 long,又如何操作?
proc transpose
首先来介绍 syntax:
PROC TRANSPOSE DATA= Dataset-name OUT= New-dataset-name;
BY variable(s);
ID variable;
VAR variable(s);
RUN;
我们分两种情况来讨论。
long data -> wide data 长转宽
by 组变量确定新 dataset 的行分类结构(wide 中 row identification variable 需要 by 组 变量唯一确定);
id 变量确定新 dataset 的列分组情况,id 变量的每一种 unique 取值在格式化后将成为转置后新数据集的新列变量名。特殊地,若 id statement 含多个变量,则这些变量取值的 unique 组合将成为新列名。要注意的是,由于 id 变量对应列分组,在新 dataset 的行分类结构已确定之下,id 变量每种取值所对应的需要转置的变量的取值在数据集中必须是唯一的;
var 指示需要进行转置填充新 dataset 中 cell 的变量,若 var 缺省,默认转置全部 numeric variables。转置中,SAS 自动创建变量 _name_,它以 var 变量名为取值。
来看 code:
data work.narrow_file2;
infile cards;
length pet_owner $10 pet $4 population 8;
input pet_owner $ pet $ population;
cards;
Mr.Black dog 2
Mr.Black cat 1
Mrs.Brown dog 1
Mrs.Brown cat 0
Mrs.Green fish 5
Mr.White fish 7
Mr.White dog 1
Mr.White cat 3
;
proc print data= work.narrow_file2 noobs;
title "原 long data";
run;
原数据集:

进行长转宽:
proc sort data= work.narrow_file2 out= work.sorted_narrow_file2;
by pet_owner;
run;
proc transpose data= work.sorted_narrow_file2 out= work.narrow_file2_transp_id_by name= column_that_was_transposed;
by pet_owner;
id pet;
var population;
run;
proc print data= work.narrow_file2_transp_id_by noobs;
title "新 wide data";
run;

看看你能不能和原数据集对应上。
wide data -> long data 宽转长
by 组变量确定新 dataset 的行分类结构(long 中单个观测多行数据,row identification variable 即为 by 组变量,by 组变量在多行间重复);
id 变量确定新 dataset 的列分组情况;
var 中每个变量将成为新 dataset 中某列变量的每一行。
上 code,将前面转置后的 wide data 转回去:
proc transpose data= work.narrow_file2_transp_id_by out= reverse name= pet;
by pet_owner;
id column_that_was_transposed;
var dog cat fish;
run;
proc print data= reverse noobs;
title "转回 long data";
run;
