【问题标题】:CSV File Processing - SASCSV 文件处理 - SAS
【发布时间】:2017-11-09 07:26:00
【问题描述】:

我对 SAS 编程非常陌生,并试图找到最有效的方法来实现我当前正在进行的计划。基本上,我需要修改存储在 SAS 服务器上的现有 .csv 文件,并将其保存在同一服务器上的文件夹中。

需要修改:

  • 保留 .csv 格式
  • 使用“|”而不是“,”作为分隔符
  • 具有以下输出名称:filename_YYYYMMDDhhmmss.csv
  • 只保留原始文件中的 4 个变量
  • 重命名我们保留的一些变量

这是我目前正在使用的脚本,但它存在一些问题:

 PROC IMPORT OUT = libname.original_file (drop=var0)
              FILE = "/.../file_on_server.csv"
              DBMS = CSV
              REPLACE;
 RUN;


%PUT date_human = %SYSFUNC(PUTN(%sysevalf(%SYSFUNC(TODAY())-1), datetime20.));

proc export data = libname.original_file ( rename= ( var1=VAR11 var2=VAR22 Type=VAR33 )) 
        outfile = '/.../filename_&date_human..csv' label dbms=csv replace;
        delimiter='|';
run;

我在重命名变量“Type”时也遇到了问题,因为它看起来与某些系统关键字冲突。日期格式也不好,很遗憾,我在 SAS 论坛上找不到确切的格式。

非常感谢任何有关如何使此脚本更高效的建议。

【问题讨论】:

    标签: csv import sas export


    【解决方案1】:

    我不会费心尝试将数据实际读入 SAS 数据集。只需处理它并将其写回即可。如果输入结构是一致的,那么它非常简单。只需将所有内容读取为字符串并输出您要保留的列。

    假设数据有 12 列,而要保留的四列中的最后一列是第 10 列。所以你只需要读入其中的 10 个。

    首先在宏变量中设置输入和输出文件名,以便于编辑。您可以使用您的逻辑为新文件生成文件名。

    %let infile=/.../file_on_server.csv;
    %let outfile=/.../filename_&date_human..csv;
    

    然后使用简单的 DATA _NULL_ 步骤以字符串形式读取数据并将其写回。如果需要,您甚至可以更改四列的相对顺序。所以这个程序将复制第 2、5、4 和 10 列,并将列标题更改为 NewName1、NewName2、NewName3 和 NewName4。

    data _null_;
      infile "&infile" dsd dlm=',' truncover;
      file "&outfile" dsd dlm='|';
      length var1-var10 $200 ;
      input var1-var10;
      if _n_=1 then do;
         var2='NewName1';
         var5='NewName2';
         var4='NewName3';
         var10='NewName4';
      end;
      put var2 var5 var4 var10 ;
    run;
    

    如果您要保留的四列的某些数据超过 200 个字符,则只需更新 LENGTH 语句。

    所以让我们做一个小实验。首先让我们制作一个虚拟的 CSV 文件。

    filename example temp;
    data _null_;
      file example ;
      input;
      put _infile_;
    cards4;
    a,b,c,d,e,f,g,h,i,j,k,l,m
    1,2,3,4,5,6,7,8,9,10,11,12,13
    o,p,q,r,s,t,u,v,w,x,y,z
    ;;;;
    

    现在让我们尝试运行它。我将修改 INFILE 和 FILE 语句以从我的临时文件中读取并将结果写入日志。

      infile example /* "&infile" */ dsd dlm=',' truncover;
      file log /* "&outfile" */ dsd dlm='|';
    

    这是写入的结果行。

    NewName1|NewName2|NewName3|NewName4
    2|5|4|10
    p|s|r|x
    

    【讨论】:

    • 非常感谢您提供如此详细的解释!为什么我可以获得必要的新变量名,但内容都是空的?
    • 确保 PUT 在 IF 块之后。还要确保数据行实际上是用逗号分隔的。由于 IF 块强制第一条记录的值,因此第一行也可能被读取为空。添加此语句以转储前 5 行。 if _n_ <= 5 then putlog _infile_;
    • 我试图修复我的脚本,但我仍然没有得到任何结果,但值由“|”分隔按照规定。
    • 我喜欢使用LIST 语句来查看源文本文件。 data _null_; infile "&infile" obs=5; list; run; 也许您的源文件不是 csv 文件?还是你的文件名有误?如果它真的是大型机,它可能在 EBCDIC 中?
    • 输入是 csv,当我在我的 proc 导入/导出中使用相同的宏变量时,路径是正确的。我很想在没有中间数据集的单个脚本中运行这项工作,但在这里调试仍然没有成功。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-13
    • 2014-08-10
    • 2013-11-27
    • 2015-02-20
    相关资源
    最近更新 更多