使用外部描述文件将固定列数据输入SAS

时间:2013-12-16 18:52:56

标签: sas

我正在尝试将Nielsen Claritas数据输入固定列格式的SAS。看起来好像只有1000个变量。每个.dat文件都包含描述性文本文件。我想可能有一种方法可以利用这个描述性的txt文件来指定输入长度,名称,格式等等。有人能用最简单的方法给我一个想法吗?

经过几个小时的搜索,我找不到任何预制函数,我最好的猜测是用do循环重新格式化描述性txt文件。如果任何这些程序提供更简单的方法,我也可以访问并体验R,Stata和SAS Enterprise指南。

这是描述性文件的一个示例:

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

4 个答案:

答案 0 :(得分:1)

通常,您需要创建一个如下所示的数据集:

colname | start | length | 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;

您也可以分配格式/等,具体取决于数据,布局和您想要的结果。

答案 1 :(得分:0)

或者您可以使用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;

答案 2 :(得分:0)

听起来您想要生成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:\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;

答案 3 :(得分:-2)

是的,我必须处理相同的数据......这并不好玩。我一直在做的是从文本文件中复制所有数据并将它们粘贴到Excel中 - 单元格A4(使用文本到列 - 固定宽度文本列)。然后我在Excel中使用语法来修复darn格式化......

= IF(A4<>"",IF(B5 ="",CONCATENATE(C4&""& C5),C4 ),"")

然后我一直在排序数据以消除空格。任何想法如何清理这些数据或将其导入SQL都会有所帮助。