如何从 SAS 中的较大文件创建截断的永久数据库

How to create a truncated permanent database from a larger file in SAS

我正在尝试将逗号分隔的 .txt 文件(在下面的代码中称为 'file.txt')读入 SAS,以便创建一个仅包含一些变量和观察结果的永久数据库。

以下是 .txt 文件的片段供参考:

SUMLEV,REGION,DIVISION,STATE,NAME,POPESTIMATE2013,POPEST18PLUS2013,PCNT_POPEST18PLUS
10,0,0,0,United States,316128839,242542967,76.7
40,3,6,1,Alabama,4833722,3722241,77
40,4,9,2,Alaska,735132,547000,74.4
40,4,8,4,Arizona,6626624,5009810,75.6
40,3,7,5,Arkansas,2959373,2249507,76

我的(简写)代码如下:

options nocenter nodate ls=72 ps=58;
filename foldr1 'C:\Users\redacted\Desktop\file.txt';
libname foldr2 'C:\Users\redacted\Desktop\Data';
libname foldr3 'C:\Users\redacted\Desktop\Formats';
options fmtsearch=(FMTfoldr.bf_fmts);

proc format library=foldr3.bf_fmts;
[redacted]
run;

data foldr2.file;
infile foldr1 DLM=',' firstobs=2 obs=52;
input STATE $ NAME $ REGION $ POPESTIMATE2013;
PERCENT=POPESTIMATE2013/316128839;
format REGION $regfmt.;
run;

proc print data=foldr2.file;
sum POPESTIMATE2013 PERCENT;
title 'Title';
run;

在我的 INPUT 语句中,我列出了我想要包含在我的新截断数据库中的变量(STATE、NAME、REGION 等)。

当我打印截断的数据库时,我注意到我的所有 INPUT 变量 而不是 对应于原始文件中的相同变量。 相反,我的变量打印如下:

似乎 SAS 正在根据顺序而不是名称匹配我的 INPUT 变量。因此,因为我在 INPUT 语句中列出了 STATE first,SAS 打印出原始 .txt 文件的 first 变量(即,SUMLEV 变量)。

知道我的代码有什么问题吗?感谢您的帮助!

您当前的数据步骤是告诉 SAS 如何命名 txt 文件中的前四个变量。要执行您想要的操作,您需要在 "input" 语句中列出 txt 文件中的所有变量。然后,在您的数据语句中,使用 keep= 选项 select 您希望包含在输出数据集中的变量。

data foldr2.file (keep=STATE NAME REGION POPESTIMATE2013 PERCENT);
  infile foldr1 DLM=',' firstobs=2 obs=52;
  input
    SUMLEV
    REGION $
    DIVISION
    STATE $
    NAME $
    POPESTIMATE2013
    POPEST18PLUS2013
    PCNT_POPEST18PLUS;
  PERCENT=POPESTIMATE2013/316128839;
  format REGION $regfmt.;
run;

您当前的代码正在读取 CSV 文件每一行的前 4 个值,并将它们分配给具有您列出的名称的列。

input 语句列出了您要读入的所有列(以及从何处读取它们),它不会在输入文件中搜索命名列。

下面的代码应该会产生您想要的输出。 keep 语句列出了您希望在输出中出现的列。

data foldr2.file;
    infile foldr1 dlm = "," firstobs = 2 obs = 52;
    /* Prevent truncating the name variable */
    informat NAME .;
    /* Name each of the columns */
    input SUMLEV REGION DIVISION STATE NAME $ POPESTIMATE2013 POPEST18PLUS2013 PCNT_POPEST18PLUS;
    /* Keep only the columns you want */
    keep STATE NAME REGION POPESTIMATE2013 PERCENT;
    PERCENT = POPESTIMATE2013/316128839;
    format REGION $regfmt.;
run;

有关稍微复杂的解决方案,请参阅 Joe 的出色回答 here。将此方法应用于您的数据需要提前设置列的长度并将字符值转换为数字。

data foldr2.file;
    infile foldr1 dlm = "," firstobs = 2 obs = 52;
    length STATE 8. NAME . REGION 8. POPESTIMATE2013 8.;
    input @;
    STATE = input(scan(_INFILE_, 4, ','), best.);
    NAME = scan(_INFILE_, 5, ',');
    REGION = input(scan(_INFILE_, 2, ','), best.);
    POPESTIMATE2013 = input(scan(_INFILE_, 6, ','), best.);
    PERCENT = POPESTIMATE2013/316128839;
    format REGION $regfmt.;
run;

如果您希望更熟悉 SAS,那么值得您花时间看看 SAS documentation 来读取文件。