web-dev-qa-db-ja.com

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.
_

説明されている ここ および ここ :コンパイラは変数と形式のさまざまなタイプを検出し、それが間違いであると想定し、推定された欠落_$_を追加します。 tフォーマットを見つけます。

たとえば、次のような2番目の変数を作成した場合、これらすべての試行は機能します。

_DATA test4;
  SET test (rename=(x=x2));
  x = x2*1;
  drop x2;
run;
_

しかし、私は自分のコードをクリーンアップしようとしていますが、そうせずにそのような変換を行う方法があるのだろうか?

7
Vincent

他の場所で述べたように、2番目の変数を使用する必要があります。 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;
9
Joe

変数が数値または文字で定義されると、そのデータ型を変更することはできませんが、おそらく以下の回避策を使用できます。

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;
4
NEOmen

以前のソリューションの問題は、インデックスが保持されないことです。

ターゲットを「インプレース」で更新する場合は、次の解決策が推奨されます(ただし、ターゲット列自体がインデックス内にある場合は、問題が発生します)。

%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_;
2
Allan Bowe