使用外部描述文件将固定列数据输入SAS
我正在尝试将尼尔森克拉利塔的数据输入到SAS中,SAS采用固定列格式。看起来只有不到1000个变量。每个.dat文件都包含描述性文本文件。我想可能有一种方法可以利用这个描述性的txt文件来指定输入长度、名称、格式等等。有人能给我一个最简单的方法吗 经过几个小时的搜索,我找不到任何固定函数,我的最佳猜测是用do循环重新格式化描述性txt文件。如果这些程序中的任何一个能够提供更简单的方法,我也可以使用R、Stata和SAS Enterprise guide,并有使用这些程序的经验 这是描述性文件的一个示例:使用外部描述文件将固定列数据输入SAS,sas,Sas,我正在尝试将尼尔森克拉利塔的数据输入到SAS中,SAS采用固定列格式。看起来只有不到1000个变量。每个.dat文件都包含描述性文本文件。我想可能有一种方法可以利用这个描述性的txt文件来指定输入长度、名称、格式等等。有人能给我一个最简单的方法吗 经过几个小时的搜索,我找不到任何固定函数,我的最佳猜测是用do循环重新格式化描述性txt文件。如果这些程序中的任何一个能够提供更简单的方法,我也可以使用R、Stata和SAS Enterprise guide,并有使用这些程序的经验 这是描述性文件的一
RECORD LAYOUT: 2013.1 Pop-Facts Premier (2000) Data (ZIP Codes Level)
POSITION TYPE SIZE CONTENTS
1- 2 A 2 Record Type
3- 4 A 2 FIPS State Code
5- 7 A 3 FIPS County Code
8- 12 A 5 FIPS Minor Civil Division (MCD) Code
13- 18 A 6 Census Tract Code
19- 19 A 1 Census Block Group (BG) Code
20- 23 A 4 Metropolitan Statistical Area or New England County
Metro Area (MSA/NECMA) Code
24- 28 A 5 Core Based Statistical Area Code
29- 33 A 5 ZipCode
34- 38 A 5 FIPS Place Code
39- 41 A 3 Designated Marketing Area (DMA) Code
42- 43 A 2 Congressional District Code
44- 63 A 20 State Name
64- 95 A 32 County Name
96- 145 A 50 Core Based Statistical Area Name
146- 177 A 32 Geography Name
178- 192 A 15 Geography Code (Concatenated Geography Code)
193- 202 F 10.6 Latitude
203- 213 F 11.6 Longitude
2000 Population by Single Race and Sex
337- 345 I 9 2000 Population, White Alone
346- 354 I 9 2000 Population, White Alone, Male
355- 363 I 9 2000 Population, White Alone, Female
364- 372 I 9 2000 Population, Black/African American Alone
373- 381 I 9 2000 Population, Black/African American Alone, Male
382- 390 I 9 2000 Population, Black/African American Alone, Female
391- 399 I 9 2000 Population, American Indian/Alaskan Native Alone
400- 408 I 9 2000 Population, American Indian/Alaskan Native Alone,
Male
409- 417 I 9 2000 Population, American Indian/Alaskan Native Alone,
Female
418- 426 I 9 2000 Population, Asian Alone
427- 435 I 9 2000 Population, Asian Alone, Male
436- 444 I 9 2000 Population, Asian Alone, Female
445- 453 I 9 2000 Population, Native Hawaiian/Pacific Islander Alone
454- 462 I 9 2000 Population, Native Hawaiian/Pacific Islander
Alone, Male
463- 471 I 9 2000 Population, Native Hawaiian/Pacific Islander
Alone, Female
472- 480 I 9 2000 Population, Some Other Race Alone
481- 489 I 9 2000 Population, Some Other Race Alone, Male
490- 498 I 9 2000 Population, Some Other Race Alone, Female
499- 507 I 9 2000 Population, Two or More Races
508- 516 I 9 2000 Population, Two or More Races, Male
517- 525 I 9 2000 Population, Two or More Races, Female
通常,您需要创建一个如下所示的数据集:
colname | start | length | informat
其中informat至少包含$或不包含任何内容,并且可能包含一些关于它是否是日期/等的信息
然后您可以编写一个宏,如下所示:
%macro readincol(col,start,len,informat);
@&start. &col. &informat.$len..
%mend readincol;
然后将第一个数据集的行读入宏变量,如下所示:
proc sql;
select cats('%readincol(',colname,',',start,',',length,',',informat,')') into :inputst
separated by ' ' from layout_dset;
quit;
现在,您已经构建了输入语句,可以在datastep中使用它:
data want;
infile "myfile.txt" lrecl=32767;
input
&inputst.
;
run;
您还可以根据数据、布局和所需结果分配格式等。或者您可以在创建布局数据集后在一个数据步骤中完成,如Joe的回答中使用CALL EXECUTE:
data _null_;
call execute(
"data want;
infile 'myfile.txt' lrecl=32767;
input");
do until(eof);
set layout_dset end=eof;
call execute(cats("@",start)||colname||" "||cats(informat,length,"."));
end;
call execute(";run;");
run;
听起来您想要生成SAS代码来读取描述性文本文件并创建SAS数据集。真的没有一个好方法告诉你怎么做;使用您提供的数据向您展示一个示例程序更容易 下面应该给你一个好的开始。注意,您的源代码描述没有提供和列名,所以我只使用了一个范围VARnnn。您需要为每个要处理的文件修改此程序,输入是一个文本文件,正如您所示;输出是另一个包含SAS程序的文本文件 还请注意,您没有提供读取任何日期或日期时间值的示例;如果这些存在于某个地方,您将需要进行适当的更改 下面是使用您提供的示例测试的代码:
data inputs(keep=input_stmt)
vars(keep=attrib dslabel);
length dslabel $60 input_stmt attrib $200;
retain varnum 0 dslabel;
infile 'c:\temp\table1.txt' truncover;
input @;
if _infile_ =: 'RECORD LAYOUT:' then do;
dslabel = substr(_infile_,16);
input ///; /* skip next 3 lines */
delete;
end;
input @1 START $5. @7 END 5. @15 TYPE $1. @17 SIZE $4. @25 LABEL $80.;
if START ne ' '; /* ignore blank and non-data lines */
varnum + 1; /* Variable counter */
varname = 'VAR' || put(varnum,z3.);
select(TYPE);
when( 'A' ) infmt = '$' || trim(SIZE) || '.';
when( 'F' ) infmt = SIZE;
when( 'I' ) infmt = trim(SIZE) || '.';
otherwise infmt = '$' || trim(SIZE) || '.'; /* Read as character */
end;
attrib = 'ATTRIB ' || trim(varname) || ' INFORMAT='
|| trim(infmt) || " LABEL='" || trim(label) || "';";
input_stmt = '@' || trim(start) || ' ' || trim(varname) || ' '
|| trim(infmt);
run;
data _null_;
file 'c:\temp\read_table1.sas' new;
set vars;
if _n_ = 1 then
put "data table1(label='" dslabel "');";
put attrib;
run;
data _null_;
file 'c:\temp\read_table1.sas' mod;
set inputs end=eof;
if _n_ = 1 then
put 'input';
put @5 input_stmt;
if eof then put ';' / 'run;';
run;
是的,我不得不处理同样的数据。。。这不好玩。我一直在做的是复制文本文件中的所有数据,并使用文本到列(固定宽度的文本列)将它们粘贴到Excel的单元格A4中。然后我正在使用Excel中的语法修复该死的格式化 =IFA4,IFB5=,连接EC4和C5,C4
然后我一直在对数据进行排序,以消除空格。任何关于如何清理此数据或按原样将其导入SQL的想法都会有所帮助 您能否发布一个描述性文本文件的示例,以及您自己试图解决此问题的一些代码?你可能只需要一个简单的宏。是的,谢谢你,约翰。我已经编辑了原始文章以包含描述文件的示例。我还没有写过任何代码,因为如果有一个预先存在的屏蔽函数,重新设计轮子似乎效率低下。