我正试图将Nielsen Claritas数据输入固定列格式的SAS。看起来只有不到1000个变量。每个.dat文件都包含描述性文本文件。我想可能有一种方法可以利用这个描述性的txt文件来指定输入长度、名称、格式等。有人能给我一个最简单的方法吗?
经过几个小时的搜索,我找不到任何固定的函数,我的最佳猜测是用do循环重新格式化描述性的txt文件。如果这些程序中的任何一个能提供更简单的方法,我也可以访问R、Stata和SAS企业指南,并有经验。
这是描述文件的一个示例:
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;
现在您已经构建了输入语句,并且可以在数据步骤中使用它:
data want;
infile "myfile.txt" lrecl=32767;
input
&inputst.
;
run;
您还可以指定格式等。,取决于数据、布局和您想要的结果。
或者您可以使用CALL EXECUTE:在一个DATA步骤中完成(在创建布局数据集之后,如Joe的回答中所示)
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程序的另一个文本文件。
还要注意,您没有提供读取任何DATE或DATETIME值的示例;如果这些存在于某个地方,则需要进行适当的更改。
以下是代码(使用您提供的示例进行测试):
data inputs(keep=input_stmt)
vars(keep=attrib dslabel);
length dslabel $60 input_stmt attrib $200;
retain varnum 0 dslabel;
infile 'c:temptable1.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:tempread_table1.sas' new;
set vars;
if _n_ = 1 then
put "data table1(label='" dslabel "');";
put attrib;
run;
data _null_;
file 'c:tempread_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中的语法来修复该死的格式。。。
=IF(A4<>",IF(B5=",CONCATENATE(C4&"&C5),C4),")
然后我一直在对数据进行排序以消除空格。任何关于如何清理这些数据或按原样将其导入SQL的想法都会很有帮助。