【问题标题】:How can I make a character variable equal to the formatted value of a numeric variable for arbitrary SAS formats?如何使字符变量等于任意 SAS 格式的数字变量的格式化值?
【发布时间】:2011-10-24 16:47:13
【问题描述】:

如果我有一个带格式的数字变量,有没有办法将格式化的值作为字符变量获取?

例如我想写类似下面的东西来打印10/06/2009到屏幕但是没有putformatted()函数。

data test;
  format i ddmmyy10.;
  i = "10JUN2009"d;
run;

data _null_;
  set test;
  i_formatted = putformatted(i); /* How should I write this? */
  put i_formatted;
run;

(显然我可以写put(i, ddmmyy10.),但我的代码需要适用于i 碰巧有的任何格式。)

【问题讨论】:

    标签: sas


    【解决方案1】:

    VVALUE 函数使用与变量关联的格式来格式化传递给它的变量。这是使用VVALUE的代码:

    data test;
      format i ddmmyy10.;
      i = "10JUN2009"d;
    run;
    
    data _null_;
      set test;
      i_formatted = vvalue(i);
      put i_formatted;
    run;
    

    虽然 cmjohns 解决方案比这段代码稍快,但这段代码更简单,因为不涉及宏。

    【讨论】:

      【解决方案2】:

      使用vformat() 函数。

      /* test data */
      data test;
        i = "10jun2009"d;
        format i ddmmyy10.;
      run;
      
      /* print out the value using the associated format */
      data _null_;
        set test;
        i_formatted = putn(i, vformat(i));
        put i_formatted=;
      run;
      /* on log
      i_formatted=10/06/2099
      */
      

      【讨论】:

      • +1 我喜欢这个,之前不知道 putn() 或 vformat(),但出于性能原因,我接受 cmjohns 的回答。
      【解决方案3】:

      这似乎适用于我尝试过的一对夫妇。我使用 VARFMT 和宏函数来检索给定变量的格式。

       data test;
        format i ddmmyy10. b comma12.;
        i = "10JUN2009"d;
        b = 123405321;
      run;
      
      
      %macro  varlabel(variable) ;
        %let dsid=%sysfunc(open(&SYSLAST.)) ;
        %let varnum=%sysfunc(varnum(&dsid,&variable)) ;
        %let fmt=%sysfunc(varfmt(&dsid,&varnum));
        %let dsid=%sysfunc(close(&dsid)) ;
        &fmt
      %mend varlabel;
      
      data test2;
        set test;
        i_formatted = put(i, %varlabel(i) );
        b_formatted = put(b, %varlabel(b) );
        put i_formatted=;
        put b_formatted=;
      run;
      

      这给了我:

      i_formatted=10/06/2009
      b_formatted=123,405,321
      

      【讨论】:

      • +1,我接受这个答案,因为它比 putn(i, vformat(i)) 快得多。对于 1000 万次观察,此方法需要 10 秒,而 65 秒。
      【解决方案4】:

      我可以用宏代码和sashelp.vcolumn 做到这一点,但这有点繁琐。

      proc sql noprint;
        select trim(left(format)) into :format
          from sashelp.vcolumn
          where libname eq 'WORK' and memname eq 'TEST';
      run;
      
      data test2;
        set test;
        i_formatted = put(i, &format);
        put i_formatted;
      run;
      

      【讨论】:

      • @Chang Chung 我知道这是一个老问题,但我被重定向到这里。有什么理由让您更喜欢这个而不是 cmjohns 的解决方案? @Simon同样的问题给你:你为什么说它有点繁琐?不是100%稳定吗?
      • @Yohsoog:它可以工作,而且很稳定。我只是希望有一种方法可以在不查看 sashelp.vcolumn 的情况下做到这一点。
      【解决方案5】:

      是的,有一个 putformatted() 函数。实际上有两个:putc() 和 putn()。 Putc 处理字符格式,putn() 数字。您的代码将需要查看格式名称(所有且只有字符格式以“$”开头)确定要使用的格式。这是 putc 的语法(来自交互式帮助):

      PUTC(source, format.<,w>)
      

      参数

      source 
      is the SAS expression to which you want to apply the format.
      
      format. 
      is an expression that contains the character format you want to apply to source.
      
      w 
      specifies a width to apply to the format. 
      
      Interaction: If you specify a width here, it overrides any width specification
      in the format. 
      

      【讨论】:

      • 但我必须提供格式:问题的重点是找出是否有一种方法可以使用变量的当前格式进行格式化
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-28
      • 1970-01-01
      相关资源
      最近更新 更多