SAS:将字符转换为数字而不创建另一个变量

时间:2014-12-29 12:54:18

标签: type-conversion sas

我想将x转换为数字。

DATA test;
  input x $1.;
  cards;
  1
  2
  0
  ;
run;

我尝试了不同的方法:

  • 使用*1

    /* trial1 */
    DATA test1;
      SET test;
      x = x*1;
    run;
    

日志打印以下注释:

NOTE: Character values have been converted to numeric values at the places given by: (Line):(Column).
      2470:3
NOTE: Numeric values have been converted to character values at the places given by: (Line):(Column).
      2470:4

格式没有改变。

  • 使用input()

    /* trial2 */
    DATA test2;
      SET test;
      x = input(x,BEST1.);
    run;`
    

日志打印以下注释:

NOTE: Numeric values have been converted to character values at the places given by: (Line):(Column).
  2396:3

格式没有改变。

  • 使用informat

    /* trial3 */
    DATA test3;
      SET test;
      informat x BEST1.;
    run;
    

日志会显示以下错误:

ERROR 48-59: The informat $BEST was not found or could not be loaded.

解释了herehere:编译器检测到变量和格式的不同类型,假设它是错误的,添加假定缺失的$因此不会# 39;找不到格式。

如果我创建了第二个变量,例如:

,所有这些试验都会有效
DATA test4;
  SET test (rename=(x=x2));
  x = x2*1;
  drop x2;
run;

但是我试图清理我的代码,我想知道是否有办法在没有这样做的情况下进行这样的转换?

3 个答案:

答案 0 :(得分:8)

如其他地方所述,您确实需要使用第二个变量。 SAS不会让你直接改变列的变量类型,但是你可以通过以与上面类似的方式使用重命名来欺骗事物。

我要提出的与NEOmen的答案不同的一件事就是使用input。长度/分配或使用*1方法都很好,但它们依赖于SAS的自动类型转换,它会在日志中添加一个注释,表明它正在执行此操作。你应该在你的日志中避免这样的事情,因为它们很混乱并且让别人认为你可能在事故中这样做了。

使用NEOmen的测试数据集:

data test1;
  set test(rename=x=x_old);
  x=input(x_old,best12.); *whatever is appropriate informat for your variable;
run;

答案 1 :(得分:4)

一旦变量被定义为数字或字符,你就无法改变它的数据类型,你可以使用下面的解决方法。

DATA test;
input x $1.;
cards;
1
2
0
;
run;

data test1(drop=x_old);
length x 8.;
set test(rename = (x=x_old));
x=x_old;
run;

答案 2 :(得分:2)

以前的解决方案的问题在于它们将不保留索引。

如果打算更新目标“就地”,则以下解决方案是可取的(尽管如果目标列本身在索引内,这仍然会引起问题):

%let changeds=test;
%let changevar=x;

DATA &changeds;
input &changevar $1.;
cards;
1
2
0
;
run;

proc datasets lib=work noprint;
  modify &changeds;
    rename &changevar=_willerrorifthisvarexists_;
run;

proc sql;
alter table &changeds add &changevar num;
update &changeds set &changevar=input(_willerrorifthisvarexists_,best.);
alter table &changeds drop  _willerrorifthisvarexists_;