SAS将文本写入文本文件会导致未写入日志文件的额外空间

SAS将文本写入文本文件会导致未写入日志文件的额外空间,sas,Sas,我有一个地址标准化的数据集——以STREET为例,将其替换为ST——并希望编写执行替换的代码。当测试代码时,它在日志文件中按预期显示,但在写入文本文件时会添加额外的空格。我不想要额外的空间 -=-=-=-=-=-=-SAS代码 data std ; length pre $16 post $8 ; infile datalines delimiter=',' ; input pre $ post $ ; p

我有一个地址标准化的数据集——以STREET为例,将其替换为ST——并希望编写执行替换的代码。当测试代码时,它在日志文件中按预期显示,但在写入文本文件时会添加额外的空格。我不想要额外的空间

-=-=-=-=-=-=-SAS代码

   data std ;
    
        length pre $16 post $8 ;
        infile datalines delimiter=',' ;
        input pre $ post $ ;
        
    pre = strip(pre);
    post = strip(post);
    
    datalines;  
    AVENUES ,   AVE
    AVENUE  ,   AVE
    BOULEVARD   ,   BLVD
    CIRCLE  ,   CIR
    ;
    run;
    
    data _null_ ;
    
        file "&test.txt";
        set std ;
        
    p1  =   trim(pre) ;
    p2  =   trim(post);
        
    put '&var = strip( prxchange("s/(^|\s)' p1 +(-1) '\s/ ' p2 +(-1) ' /i",-1,&var) );' ;
    
    run;
-=-=-=-=-=-=-=-=-代码结束

SAS代码生成以下内容

&var = strip( prxchange("s/(^|\s)AVENUES\s/ AVE /i",-1,&var) );

 &var = strip( prxchange("s/(^|\s)AVENUE\s/ AVE /i",-1,&var) );

 &var = strip( prxchange("s/(^|\s)BOULEVARD\s/ BLVD /i",-1,&var) );
。。。在日志文件中删除file语句时,但写入

&var = strip( prxchange("s/(^|\s)AVENUES    \s/     AVE /i",-1,&var) );

&var = strip( prxchange("s/(^|\s)AVENUE \s/     AVE /i",-1,&var) );

&var = strip( prxchange("s/(^|\s)BOULEVARD  \s/     BLVD /i",-1,&var) );
。。。文件test.txt中的REGEX函数中有额外的空格


这是SAS 9.4,我正在通过基于web的SAS Studio使用它。

因此,您的问题在于SAS如何存储字符变量

字符变量始终等于该变量中存储的字符,后跟填充数据存储长度所需的任意多个空格(
'20'x
)字符。这与具有字符串终止符或类似字符的语言(大多数是较新的)不同;SAS没有这样的字符,它只是用空格填充空格。因此,如果变量长度为8字节,并且包含
Avenue
,那么它实际上包含
Avenue

您不能在代码中,在一行代码之外更改它。所以,你的台词:

p1  =   trim(pre) ;
p2  =   trim(post);
它们毫无意义——它们除了浪费CPU时间之外什么都不做(可悲的是,它们没有优化我所能说的)

您需要在使用该值的行中进行修剪,因为在那里它可以被修剪掉。现在,您不能将
放入
修剪(…)
,因此您需要撰写行以便在其他地方写入,或者使用

这里有一个例子:

filename tempfile temp;

data _null_ ;    
    file tempfile;
    set std ;        
    result = cats('&var = strip( prxchange("s/(^|\s)',pre,catx(' ','\s/',post,'/i",-1,&var) );'));
    put  result ;

run;

data _null_;
  infile tempfile;
  input @;
  put _infile_;
run;
下面是一个使用
$variable的示例。

data _null_ ;    
    file tempfile;
    set std ;        
    varlen_pre = length(pre);
    varlen_post = length(post);
      put '&var = strip( prxchange("s/(^|\s)' pre $varying16. varlen_pre  '\s/ ' post $varying8. varlen_post  ' /i",-1,&var) );' ;

run;
至于日志与文件不匹配的原因,这是因为SAS写入日志的规则与写入文件的规则略有不同。它更准确地描述了它写入文件的内容;你说它,它写它。对于日志,它有几个地方可以为您删除空间,大概是为了让日志更可读,因为不需要精确。当您确实希望日志中的精度时,这可能是一种痛苦,当然,在您希望日志与您看到的内容匹配的情况下


最后,请注意您正在做的事情。我不强烈建议您使用正则表达式的方式。非常慢。除非你只做了少量的替换,或者只有一个小的数据集大小,或者真的不在乎这需要多长时间

如果只是1:1的替换,我建议使用更快的
tranwrd
。请看这个小比较:

data in_data;
  do _n_ = 1 to 1e5;
    address = catx(' ',rand('Integer',1,9999),'Avenue');
    output;
    address = catx(' ',rand('Integer',1,9999),'Street');
    output;
    address = catx(' ',rand('Integer',1,9999),'Boulevard');
    output;
    address = catx(' ',rand('Integer',1,9999),'Circle');
    output;
    address = catx(' ',rand('Integer',1,9999),'Route');
    output;
    
  end;
run;

data want;
  set in_data;

  rx_ave  = prxparse('s/(^|\s)Avenue\s/ Ave /ios');
  rx_st   = prxparse('s/(^|\s)Street\s/ St/ios');
  rx_blvd = prxparse('s/(^|\s)Boulevard\s/ Blvd /ios');
  rx_cir  = prxparse('s/(^|\s)Circle\s/ Cir /ios');
  
  do i = 1 to 4;
    address = prxchange(i,-1,address);
  end;
run;

data want;
  set in_data; 
    address = tranwrd(Address,'Avenue','Ave');
    address = tranwrd(address,'Street','St');
    address = tranwrd(address,'Boulevard','Blvd');
    address = tranwrd(address,'Circle','Cir');
run;

这两种方法的工作原理是一样的——假设你已经在使用“words”了——但是第二种方法的工作时间基本上与写数据集所需的时间相同(对我来说是0.15秒),而第一种方法在我的SAS服务器上需要20秒的CPU时间。加载正则表达式库非常慢。

谢谢Joe。我从没听说过$variable格式。我没有看到一个按钮,上面写着“这是回答”或类似的,我太新了,不能投票。不管怎样,再次感谢。回答是一个绿色的复选标记-应该在投票点附近。如果有帮助的话,我确实添加了更多的细节!不管好坏我刚刚在带有TRANWRD的Linux机器上用SAS 9.4做了一些测试,它产生了不同的结果。尽管引用了“word”,但它似乎没有找到像FINDW函数那样的“words”。它似乎可以直接替换字符串。address=“1 PLACENTIA DRIVE”。。。而且。。。clean=transwrd(地址,'PLACE','PL')导致。。。clean=“1 PLNTIA DRIVE”@GeofGee是的,它不是像
FINDW那样的“word”。您可以添加空格-
tranwrd(address,'Avenue','Ave')
或类似的-或者可能比正则表达式快很多倍的测试。如果有人介意,在步骤开始时,我在左边界添加了一个空格,使用tranwrd和空格来定义单词,然后删除末尾的空格。