如果它们都包含分隔符/和,如何导入csv文件

时间:2018-03-18 15:36:57

标签: csv sas

我有一个包含混合分隔符,/的文件。当我使用以下数据步骤将其导入SAS时:

data SASDATA.Publications ;
    infile 'R:/Lipeng_Wang/PATSTAT/Publications.csv' 
        DLM = ',' 
        DSD missover lrecl = 32767 
        firstobs = 3 ;
    input pat_publn_id :29. 
        publn_auth :$29. 
        publn_nr :$29. 
        publn_nr_original :$29. 
        publn_kind :$29. 
        appln_id :29. 
        publn_date :YYMMDD10. 
        publn_lg :$29. 
        publn_first_grant :29. 
        publn_claims :29. ;
    format publn_date :YYMMDDd10. ;
run ;

sas日志显示

NOTE: Invalid data for appln_id in line 68262946 33-34.
NOTE: Invalid data for publn_date in line 68262946 36-44.
RULE:     ----+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9
 68262946  390735978,HK,1053433,09/465,054,A1,275562685,2010-03-26,  ,0,0 62
 pat_publn_id=390735978 publn_auth=HK publn_nr=1053433 publn_nr_original=09/465 publn_kind=054
 appln_id=. publn_date=. publn_lg=2010-03-26 publn_first_grant=. publn_claims=0 _ERROR_=1
 _N_=68262944
NOTE: Invalid data for appln_id in line 68280355 33-34.
NOTE: Invalid data for publn_date in line 68280355 36-44.
 68280355  390753387,HK,1092990,60/523,466,A1,275562719,2010-03-26,  ,0,0 62
 pat_publn_id=390753387 publn_auth=HK publn_nr=1092990 publn_nr_original=60/523 publn_kind=466
 appln_id=. publn_date=. publn_lg=2010-03-26 publn_first_grant=. publn_claims=0 _ERROR_=1
 _N_=68280353

似乎我需要提交' 60 / 523,466'进入" publn_nr_original'的音量。但我该怎么做呢?

2 个答案:

答案 0 :(得分:1)

您的程序代码有两个明显的问题。

首先,您对FORMAT语句的语法错误。 :修饰符是INPUTPUT语句语法的一项功能,不应在FORMAT语句中使用。

其次,您试图将29位数字读入数字。您无法准确地将29位数存储到SAS中的数字中。如果这些值真的长于15位,则需要将它们读入字符变量。如果它们确实是较小的数字(可以存储为数字),那么您不需要在INPUT语句中包含信息规范。 SAS已经知道如何从文本文件中读取数字。在列表模式下,INPUT语句无论如何都会忽略信息的宽度。

但是您的错误消息看起来是由于文件格式不正确造成的。我怀疑前6列中有一列的值有逗号,但创建数据文件的人忘记用逗号添加值。如果您可以确定逗号应该在哪个字段中,那么您可以以可以使用的方式解析该行。

以下是一种可能有效的方法,假设逗号只出现在publn_nr_original变量中,并且最多只显示一个逗号。

data want ; 
 infile cards dsd truncover firstobs=3;
 length
 pat_publn_id $30
 publn_auth $30
 publn_nr $30
 publn_nr_original $30
 publn_kind $30
 appln_id $30
 publn_date 8
 publn_lg $30
 publn_first_grant $30
 publn_claims $30
;
 informat publn_date YYMMDD10. ;
 format publn_date YYMMDDd10. ;
 input @;
 if countw(_infile_,',','mq')<= 10 then input pat_publn_id -- publn_claims ;
 else do ;
   list ;
   input pat_publn_id -- publn_nr_original xxx :$30. publn_kind -- publn_claims ;
   publn_nr_original=catx(',',publn_nr_original,xxx);
   drop xxx;
 end;
cards4;
Header1
Header2
1,22,333,4444,55,6666,2010-03-26,77,8,9999
390735978,HK,1053433,09/465,054,A1,275562685,2010-03-26,  ,0,0
390735978,HK,1053433,"09/465,054",A1,275562685,2010-03-26,  ,0,0
390753387,HK,1092990,60/523,466,A1,275562719,2010-03-26,  ,0,0
;;;;

但真正的解决方案是修复创建文件的过程。所以不要在文件中有这样的行:

390735978,HK,1053433,09/465,054,A1,275562685,2010-03-26,  ,0,0

这条线应该是这样的:

390735978,HK,1053433,"09/465,054",A1,275562685,2010-03-26,  ,0,0

答案 1 :(得分:0)

好的,我明白了你的意思 - 你有一个带逗号的字段,用逗号分隔的文件,并且没有引用该字段。

为此,您必须单独阅读这两个部分并重新添加逗号,如下面的示例代码所示。

值得注意的是,您的所有值都必须使用逗号才能使用此方法!这实际上看起来像坏数据,如果您的输入字段确实是&#34; 60 / 523,466&#34;那应该是&#34;引用&#34;在您的输入文件中正确读取。

%let some_csv=%sysfunc(pathname(work))/some.csv;
data _null_;
  file "&some_csv";
  put /;
  put '390735978,HK,1053433,09/465,054,A1,275562685,2010-03-26,  ,0,0';
  put '390753387,HK,1092990,60/523,466,A1,275562719,2010-03-26,  ,0,0';
run;


data work.Publications ;
  infile "&some_csv" DLM = ',' DSD missover lrecl = 32767 firstobs = 3 ;
  input pat_publn_id :best. publn_auth :$29. publn_nr :$29. 
    publn_nr_original1 :$29. publn_nr_original2:$29. 
    publn_kind :$29. appln_id :best. 
    publn_date :YYMMDD10. publn_lg :$29. publn_first_grant :best. 
    publn_claims :best. ;
  format publn_date YYMMDDd10. ;
  publn_nr_original=cats(publn_nr_original1,',',publn_nr_original2);
run ;