在单个记录中读取多个观察值并按月分组

时间:2018-02-12 09:43:23

标签: sas

我有一个数据集,每行包含四个月度观察。

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中执行此操作?我已经尝试了@@选项,但这只能帮助我阅读行中的四个读数,并为每次读数创建一个观察值。

2 个答案:

答案 0 :(得分:1)

原始数据是分类形式。那很好!

您要求进行将数据(日期的月份部分)更改为元数据(月份名称为列)的转换。这意味着您将处理数组或变量名称列表。

我建议您以分类的形式保存数据。分类表单意味着您可以使用CLASSBY语句进行有效处理。使用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|
-------------------------------------------------------------

如果您认为必须转置数据,请将日期和月份拆分为byid

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

enter image description here