SAS CSV导入添加垃圾数据列

时间:2017-11-09 17:39:25

标签: csv sas enterprise-guide

我尝试将数据导入SAS Enterprise Guide。该文件是最初通过在Mac上保存Excel文档生成的csv。有三列,Date,DayOfYear和MonthOfYear。

我的导入代码如下所示:

DATA indata;
    INFILE '/sasdata/{path_to_file}' TERMSTR=cr DSD DLM=',';
    INPUT Date YYMMDD10. DayOfYear MonthOfYear;
    FORMAT Date YYMMDD10.;
RUN;

问题是,这会导致日期列被一列移位后的所有内容。示例输出:

Date       | DOY | MOY
2017-01-01 |     |  1
2017-01-02 |     |  2
2017-01-03 |     |  3

我的hacky解决方案是添加一个名为junk的额外列来获取所有空值,但我想尽可能地解决这个问题。下面的黑客。

DATA indata;
    INFILE '/sasdata/{path_to_file}' TERMSTR=cr DSD DLM=',';
    INPUT Date YYMMDD10. junk DayOfYear MonthOfYear;
    FORMAT Date YYMMDD10.;
RUN;

Date       | junk | DOY | MOY
2017-01-01 |      |  1  |  1
2017-01-02 |      |  2  |  1
2017-01-03 |      |  3  |  1

我试过搞乱换行和回车无济于事。我输入了DSD和DLM,但这并没有改变任何东西。似乎日期最后有一个额外的隐形字符,它最终会出现在它自己的专栏中,但当我在十六进制编辑器中查看数据时,那里什么都没有。例如

ef bb bf 32-30 31 37 2d-30 31 2d 30-31 2c 31 ...

直接从2017-01-01到逗号到1.所以没有隐藏的字符。我不确定这是怎么回事。这是我遇到这个问题的第二个文件,所以我知道这不仅仅是一件事。

总结一下我的问题,如何避免在日期变量之后为垃圾创建额外的列?

2 个答案:

答案 0 :(得分:2)

您应该使用冒号(:)在输入语句中应用信息,如下所示:

DATA indata;
    INFILE '/sasdata/{path_to_file}' TERMSTR=cr DSD DLM=',';
    INPUT Date : YYMMDD10. DayOfYear MonthOfYear;
    FORMAT Date YYMMDD10.;
RUN;

根据documentation

  

:(冒号)格式修饰符使您可以使用列表输入   在变量名称后指定信息,无论是字符还是   数字。 SAS读取,直到遇到空白列,即定义的列   变量的长度(仅限字符)或数据行的末尾,   以先到者为准。

答案 1 :(得分:1)

如果您正在读取分隔数据,那么您应该使用列表模式输入。您可以从INPUT语句中删除所有信息,也可以在:语句中的信息之前添加INPUT修饰符,这样您仍然可以使用修改后的列表模式。如果从输入语句中删除信息,则可以使用INFORMAT语句告诉SAS如何读取日期变量。

data indata;
  infile '/sasdata/{path_to_file}' termstr=cr dsd truncover ;
  length Date DayOfYear MonthOfYear 8;
  input Date DayOfYear MonthOfYear;
  informat date yymmdd. ;
  format Date yymmdd10.;
run;

当您在读取分隔数据时告诉SAS使用格式化输入时,可能会发生三件事,所有这些都很糟糕。

(1)你可以读太少的字符,所以得到错误的结果。这也会导致日期值的其余部分被读作下一列的值。

(2)读取太多字符,因此尝试将下一个分隔符作为日期的一部分或甚至是下一个值的一部分。并且可能只留下下一列的下一个值的一部分。

(3)准确读取正确数量的字符以使日期正确,但是将光标位置保持在下一个分隔符之前。然后,如果您使用DSD选项来允许空值,这将使SAS认为下一个值为null并且基本上将该行的所有其余部分转移到错误的列中。