下面是我发现从长到宽重塑数据的示例。但我无法理解代码,尤其是它们替换空白的方式以及原因。有人可以帮我理解代码吗?
示例1:重塑一个变量
我们将从一个只有一个变量的小数据集开始重新整形。我们将使用变量year和faminc(用于家庭收入)来创建三个新变量:faminc96,faminc97和faminc98。首先,让我们看一下数据集并使用proc print来显示它。
DATA long ;
INPUT famid year faminc ;
CARDS ;
1 96 40000
1 97 40500
1 98 41000
2 96 45000
2 97 45400
2 98 45800
3 96 75000
3 97 76000
3 98 77000
;
RUN ;
PROC PRINT DATA=long ;
RUN ;
Obs famid year faminc
1 1 96 40000
2 1 97 40500
3 1 98 41000
4 2 96 45000
5 2 97 45400
6 2 98 45800
7 3 96 75000
8 3 97 76000
9 3 98 77000
现在让我们来看看这个节目。重塑过程的第一步是对标识变量(famid)排序数据(使用proc排序)并保存排序数据集(longsort)。接下来,我们编写一个数据步骤来进行实际的重塑。我们将按顺序解释数据步骤中的每个语句。
PROC SORT DATA=long OUT=longsort ;
BY famid ;
RUN ;
DATA wide1 ;
SET longsort ;
BY famid ;
KEEP famid faminc96 -faminc98 ;
RETAIN faminc96 - faminc98 ;
ARRAY afaminc(96:98) faminc96 - faminc98 ;
IF first.famid THEN
DO;
DO i = 96 to 98 ;
afaminc( i ) = . ;
END;
END;
afaminc( year ) = faminc ;
IF last.famid THEN OUTPUT ;
RUN;
答案 0 :(得分:0)
这里的主要元素是SAS保留声明。 对数据集中的每个观察执行datastep。对于每次迭代,所有变量都设置为缺失,然后从数据集加载数据。 如果变量是RETAINed,它将不会被重置,但会保留上次迭代的信息。
BY famid ;
您的数据集已订购,而datastep正在使用by语句。这会初始化first.famid
和last.famid
。这些只是对于单个id组的第一次/最后一次观察而变为1的二进制文件。
RETAIN faminc96 - faminc98 ;
正如已经解释过的那样,faminc96 - faminc98
会将其值从一个datastep迭代保持到下一个。
ARRAY afaminc(96:98) faminc96 - faminc98 ;
只是一个数组,所以你可以用数字而不是名字来调用变量。
IF first.famid THEN
DO;
DO i = 96 to 98 ;
afaminc( i ) = . ;
END;
END;
对于id组中的每个第一次观察,保留的变量都会被重置。否则,您将保留一个od-group到下一个od-group的值。同样可以通过IF first.famid then call missing(of afaminc(*));
afaminc( year ) = faminc ;
根据年份将信息写入转置变量。
IF last.famid THEN OUTPUT ;
将所有值写入新变量后,只将每个id-group中的一个观察值(最后一个)输出到新数据集。由于保留了变量,所以在这一点上它们都被填充了。
这个datastep是快速且有目的的构建。但通常你可以使用proc transpose
答案 1 :(得分:0)
这是与DO UNTIL进行比较和对比的一个很好的例子(最后。它取消了在FIRST.FAMID和LAST上丢失的RETAIN和INIT。测试何时输出。这些操作只是使用内置数据步骤循环的功能。
DATA long;
INPUT famid year faminc;
CARDS;
1 96 40000
1 97 40500
1 98 41000
2 96 45000
2 97 45400
2 98 45800
3 96 75000
3 97 76000
3 98 77000
;;;;
RUN;
proc print;
run;
data wide;
do until(last.famid);
set long;
by famid;
ARRAY afaminc[96:98] faminc96-faminc98;
afaminc[year]=faminc;
end;
drop year faminc;
run;
proc print;
run;
答案 2 :(得分:0)
我强烈推荐proc转置。它会让你的生活更轻松。
http://support.sas.com/resources/papers/proceedings09/060-2009.pdf