SAS从csv文件中提取字符串变量

时间:2013-08-22 14:55:57

标签: sas

已解决(根据Neil Neyman的评论):

&var1var1不同。

DATA local.trow; 
    INFILE csvfile FIRSTOBS=&i OBS=&i;
    INPUT var1 $ var2 $ var3 $ var4 $;
    call symput('var1',var1); *Added line;
    call symput('var2',var2); *Added line;
    call symput('var3',var3); *Added line;
    call symput('var4',var4); *Added line;
RUN;

添加标有“*已添加行”的行;解决了这个问题。


问题

免责声明:我是SAS的新手,并且一直在努力解决此代码中的问题。

在一个循环中,我试图从CSV文件导入字符串变量,然后我将其中一个传递给远程服务器(var1),但我遇到了一个问题。如果我在代码顶部包含%let var1 = 'XXE';并排除我从csv文件中提取变量的部分,则远程执行工作正常,我得到了我期望的输出。

但是,如果我按原样运行代码,它似乎不会按预期处理字符串变量。例如,PROC PRINT语句产生预期输出(即它显示4个变量),但标题没有正确显示 - 看起来var1完全被跳过,而i (显示值为1)和m(值为2007)。标题显示为“Title - 1 2007”。日志在标题行附近显示以下错误:

WARNING: Apparent symbolic reference VAR1 not resolved.

远程提交也不起作用,但在突出显示&VAR1时会产生以下错误:

ERROR: Syntax error while parsing WHERE clause.
ERROR 22-322: Syntax error, expecting one of the following: a quoted string,
              a numeric constant, a datetime constant, a missing value.   

我真的对这个错误感到困惑,因为PROC PRINT语句能够打印变量(事实上它实际上看起来像是字符串)。 “引用字符串”是一种不同类型的变量吗?

如果我在代码顶部显式声明var1或手动将'XXE'输入WHERE子句,则执行远程查询。

我是否正确处理文本文件?它看起来像这样:

XXE XXA XXB XXC
XXM XXN XXI XXP
...

我的代码:

LIBNAME local 'C:\...\Pulled Data\New\';
FILENAME csvfile 'C:\...\Pulled Data\New\indexes.txt';

%macro getthedata(nrows,ystart,yend); *nrows is the number of rows in the text file;

    %GLOBAL var1 var2 var3 var4;

    %do i=1 %to &nrows;
        %do m=&ystart %to &yend;

            DATA local.trow; 
               INFILE csvfile FIRSTOBS=&i OBS=&i;
               INPUT var1 $ var2 $ var3 $ var4 $;
            RUN;

            PROC PRINT DATA = local.trow;
            TITLE "Title - &i. &var1. &m";
            var var1 var2 var3 var4;
            RUN;

            proc export data=local.trow
                outfile="C:\...\Pulled Data\New\Indices_&i._&m..csv"
                dbms=csv replace;
            run;

            signon username=_prompt_;
            %syslput VAR1 = &var1;
            rsubmit;
                    libname abc'server/sasdata';    
                    data all2009;
                         set abc.file_2007:; 
                         by index date time;
                         where index in (&VAR1) and time between '8:30:00't and '12:00:00't;
                    run;
            endrsubmit;

        %end;
    %end;
%mend getthedata;

Options MPRINT;

%getthedata(1,2007,2007)

1 个答案:

答案 0 :(得分:2)

简答:

& var1与var1不同。添加下面描述的调用symput()行,将datastep值分配给宏变量值。

 DATA local.trow; 
     INFILE csvfile FIRSTOBS=&i OBS=&i;
     INPUT var1 $ var2 $ var3 $ var4 $;
     call symput('var1',var1); 
     call symput('var2',var2);
     call symput('var3',var4); 
     call symput('var4',var4);

 RUN;

其他笔记

似乎有一种奇怪的方式可以解决这个问题,但你说你是SAS的新手,所以也许我可以给你一些指示?

  1. 在宏

    之外立即创建整个数据集
    data local.trows;
      length var1 var2 var3 var4 $3;  *assuming vars really are only 3 chars;
      infile csvfile; *this is not really a csv file, it looks space-delimited.;
                       *confusing to name it as such;
      input var1 var2 var3 var4;
    run;
    
  2. 我不明白为什么每行都有一个单独的输出csv文件?这真的是你需要的吗?

  3. 获得数据集后,您的宏可以执行以下操作:

    %macro getthedata(mdataset)
      data _null_;
       set &mdataset; #add mdataset as a macro parameter;
    
        /* automatically assigning nrows based on dataset; */
        if last then call symput('nrows',_n_); 
    
      run;     
    
      %do i=1 to &nrows;
         data _null_;
          set &mdataset;
          if &i=_n_ then do;
             call symput('var1',var1);
             call symput('var2',var2);
              /*
                etc... Doesn't seem like these really should be
                globals since they change every iteration, and
                don't seem needed outside of the macro?
               */
    
         run;
         /** now you have your vars set for the current iteration 
             and proceed with your connect code **/
    
  4. 您似乎只是在每次迭代时覆盖此数据集。那是你想做的吗?或者是否有一些其他代码/宏变量你遗漏了这个问题?

    libname abc'server/sasdata';    
                data all2009;
                     set abc.file_2007:;
    /*seems to be a random colon here ^  by the way*/