我有一个大型数据文件,其数据格式如下:国家/地区,数据类型,year1month1至year2018month7。
使用proc导入读取数据并不适用于所有数据字段。我最终修改了SAS数据步骤代码,以确保数据格式正确。
但是,我在简化代码方面遇到了麻烦,也就是说,我希望do遍历所有年月。这样,我可以使用当前日期来确定文件的日期范围,并且用于创建Year / Month变量的代码不必在文件中重复100次。
data test;
infile 'abc.csv' delimiter = ',' MISSOVER DSD lrecl=32767 firstobs=2 ;
informat Country_Name $34. ;
do i = 1940 to 2018;
do j = 1 to 12;
informat _(i)M(j) best32.;
end;
end;
informat Base_Year $1. ;
format Country_Name $34. ;
do i = 1940 to 2018;
do j = 1 to 12;
format _(i)M(j) best12.;
end;
end;
format Base_Year $1. ;
input
Country_Name $
do i = 1940 to 2018;
do j = 1 to 12;
_(i)M(j) $;
end;
end;
Base_Year $;
run;
答案 0 :(得分:0)
这里有一些可行的方法。与您的方法最直接相关的翻译是使用宏语言。
您需要将这两个循环翻译成这样:
%do i = 1940 %to 2018;
%do j = 1 %to 12;
informat _&i.M&j. best32.;
%end;
%end;
注意%
。这也必须在宏中。您无法在正常的数据步骤代码中执行此操作。
我将其重写为使用如下宏:
%macro make_ym(startyear=, endyear=, separator=);
%local i j;
%do i = &startyear. %to &endyear.;
%do j = 1 %to 12;
_&i.&separator.&j.
%end;
%end;
%mend make_ym;
data test;
infile 'abc.csv' delimiter = ',' MISSOVER DSD lrecl=32767 firstobs=2 ;
informat Country_Name $34. ;
informat %make_ym(startyear=1940,endyear=2018,separator=M) best32.;
informat Base_Year $1. ;
format %make_ym(startyear=1940,endyear=2018,separator=M) best12.;
format Base_Year $1. ;
input
Country_Name $
%make_ym(startyear=1940,endyear=2018,separator=M)
Base_Year $;
run;
由于您将它们声明为数字,因此我在输入的yMm位之后取出了$
。
答案 1 :(得分:0)
不要在PROC IMPORT生成的代码之后对数据步骤建模。它做了很多无用的事情,例如将格式和信息附加到不需要它们的变量上。
对于您的问题,您只需要一个简单的程序,如下所示:
data test;
infile 'abc.csv' dsd dlm= ',' truncover firstobs=2 ;
input Country_Name :$34. Y1940M01 .... Y2018M08 Base_Year :$1. ;
run;
现在,唯一棘手的部分是建立数字变量列表。如果列表足够小,则可以将其放入宏变量中。幸运的是,在这种情况下这不是问题,因为使用8个字符名称(YyyyyMmm
)可以使数据步骤字符变量中的值超过300年。长度为10,800字节的变量应该可以容纳100年的月份名称。
因此,请首先运行此数据步骤。
data _null_;
length names $10800 ;
basedate = mdy(1,1,1940);
lastdate = today();
do i=0 to intck('month',basedate,lastdate);
date=intnx('month',basedate,i);
names=catx(' ',names,cats('Y',year(date),'M',put(month(date),Z2.)));
end;
call symputx('names',names);
run;
现在,您可以在INPUT语句中使用宏变量了。
data test;
infile 'abc.csv' dsd dlm= ',' truncover firstobs=2 ;
input Country_Name :$34. &names Base_Year :$1. ;
run;