我有一个数据集,每行包含四个月度观察。
1Sep11 389.00 1Oct11 491.00 1Nov11 370.00 1Dec11 335.00
2Sep11 423.00 2Oct11 478.00 2Nov11 407.00 2Dec11 442.00
3Sep11 482.00 3Oct11 300.00 3Nov11 303.00 3Dec11 372.00
我需要有一个数据集,其中包含四个列(9月,10月,11月,12月),每个月的读数位于右栏。实施例。
Day|Sep|Oct|Nov|Dec
1|389.00|491.00|370.00|335.00
2|423.00|478.00|407.00|442.00
3|482.00|300.00|303.00|372.00
我如何在SAS中执行此操作?我已经尝试了@@选项,但这只能帮助我阅读行中的四个读数,并为每次读数创建一个观察值。
答案 0 :(得分:1)
原始数据是分类形式。那很好!
您要求进行将数据(日期的月份部分)更改为元数据(月份名称为列)的转换。这意味着您将处理数组或变量名称列表。
我建议您以分类的形式保存数据。分类表单意味着您可以使用CLASS
和BY
语句进行有效处理。使用Proc TABULATE
排列数据项以进行输出或传递消耗(例如ODS EXCEL)。
data have;
attrib date informat=date9. format=date9.;
input date value @@;
date_again = date;
datalines;
1Sep11 389.00 1Oct11 491.00 1Nov11 370.00 1Dec11 335.00
2Sep11 423.00 2Oct11 478.00 2Nov11 407.00 2Dec11 442.00
3Sep11 482.00 3Oct11 300.00 3Nov11 303.00 3Dec11 372.00
run;
proc tabulate data=have;
class date date_again;
var value;
format date monname.;
format date_again day.;
table date_again='', date=''*value=''*max='' / nocellmerge;
run;
ODS LISTING输出
-------------------------------------------------------------
| | September | October | November | December |
|-------+------------+------------+------------+------------|
|1 | 389.00| 491.00| 370.00| 335.00|
|-------+------------+------------+------------+------------|
|2 | 423.00| 478.00| 407.00| 442.00|
|-------+------------+------------+------------+------------|
|3 | 482.00| 300.00| 303.00| 372.00|
-------------------------------------------------------------
如果您认为必须转置数据,请将日期和月份拆分为by
和id
data have2(keep=day month value);
attrib date informat=date9. format=date9.;
input date value @@;
day = day(date);
month = put(date,monname3.);
datalines;
1Sep11 389.00 1Oct11 491.00 1Nov11 370.00 1Dec11 335.00
2Sep11 423.00 2Oct11 478.00 2Nov11 407.00 2Dec11 442.00
3Sep11 482.00 3Oct11 300.00 3Nov11 303.00 3Dec11 372.00
run;
proc transpose data=have2 out=want2(drop=_name_);
by day;
var value;
id month;
run;
当整个日期范围超过一年,或者原始数据行不是按月分组或无序时,您也会遇到问题。
答案 1 :(得分:0)
代码:
/* Step 1: Read each line in a string*/
data raw;
input line $ 1-70;
cards;
1Sep11 389.00 1Oct11 491.00 1Nov11 370.00 1Dec11 335.00
2Sep11 423.00 2Oct11 478.00 2Nov11 407.00 2Dec11 442.00
3Sep11 482.00 3Oct11 300.00 3Nov11 303.00 3Dec11 372.00
;;;
run;
/*Step 2: Exract the individual values separated by space */
data input;
set raw;
September= input(scan(line,1,' '),date7.);
S_Value= scan(line,2,' ');
October= input(scan(line,3,' '),date7.);
O_Value= scan(line,4,' ');
November= input(scan(line,5,' '),date7.);
N_Value= scan(line,6,' ');
December= input(scan(line,7,' '),date7.);
D_Value= scan(line,8,' ');
format September October November December date7. ;
drop line;
put _ALL_;
run;
输出:
September=01SEP11 S_Value=389.00 October=01OCT11 O_Value=491.00
November=01NOV11 N_Value=370.00 December=01DEC11 D_Value=335.00 _ERROR_=0 _N_=1
September=02SEP11 S_Value=423.00 October=02OCT11 O_Value=478.00
November=02NOV11 N_Value=407.00 December=02DEC11 D_Value=442.00 _ERROR_=0 _N_=2
September=03SEP11 S_Value=482.00 October=03OCT11 O_Value=300.00
November=03NOV11 N_Value=303.00 December=03DEC11 D_Value=372.00 _ERROR_=0 _N_=3