0

proc univariateデータセット内の変数のカスタム変位値を計算するために使用するマクロを作成しました (たとえばdsn1) %cust_quants(dsn= , varlist= , quant_list= )dsn2出力は、次のような要約データセット (たとえば) です。

q_1      q_2.5      q_50      q_80      q_97.5      q_99      var_name
1        2.5        50        80        97.5        99        ex_var_1_100
-2       10         25        150       500         20000     ex_var_pos_skew
-20000   -500       -150      0         10          50        ex_var_neg_skew

私がやりたいことは、要約データセットを使用して、元のデータセットの極端な値を上限/下限にすることです。私の考えは、対象の列を抽出し (たとえばq_99)、それをマクロ変数のベクトル (たとえば ) に入れることq_99_1, q_99_2, ..., q_99_nです。次に、次のようなことができます。

/* create summary of dsn1 as above example */
%cust_quants(dsn= dsn1, varlist= ex_var_1_100 ex_var_pos_skew ex_var_neg_skew, 
             quant_list= 1 2.5 50 80 97.5 99);

/* cap dsn1 var's at 99th percentile */
data dsn1_cap;
  set dsn1;

  if ex_var_1_100 > &q_99_1 then ex_var_1_100 = &q_99_1;
  if ex_var_pos_skew > &q_99_2 then ex_var_pos_skew = &q_99_2;
  /* don't cap neg skew */
run;

ではR、これを行うのは非常に簡単です。インデックスのようなマトリックスを使用してデータフレームからサブデータを抽出し、このサブデータをオブジェクトに割り当てることができます。この 2 番目のオブジェクトは、後で参照できます。例 - data-frame からのR抽出:ba

> a <- as.data.frame(cbind(c(1,2,3), c(4,5,6)))
> print(a)
  V1 V2
1  1  4
2  2  5
3  3  6
> a[, 2]
[1] 4 5 6
> b <- a[, 2]
> b[1]
[1] 4

SASで同じことをすることは可能ですか? サブデータの列をマクロ変数/配列に割り当てて、2 番目のデータ ステップ内でマクロ/配列を使用できるようにしたいと考えています。1つの考えはproc sql into:次のとおりです。

proc sql noprint;
  select v2 into :v2_macro separated by " "
  from a;
run;

ただし、実際に必要なのは変数のベクトル (または配列 - SAS ではベクトルではない) である場合、これは単一の文字列変数を作成します。もう1つの考えは、追加すること%scanです(これがマクロ内にあると仮定します):

proc sql noprint;
  select v2 into :v2_macro separated by " "
  from a;
run;

%let i = 1;
%do %until(%scan(&v2_macro, &i) = "");
  %let var_&i = %scan(&v2_macro, &i);
  %let &i = %eval(&i + 1);
%end;

これは非効率的で、多くのコードが必要です。また、プログラマーは、var_&iそれぞれの将来の目的に対応するものを覚えておく必要があります。これを行うためのより簡単でクリーンな方法はありますか?

**これが十分な背景/例である場合は、コメントでお知らせください。必要に応じて、なぜ私が試みていることを行っているのかについて、より完全な説明を提供できることをうれしく思います。

4

1 に答える 1

0

まず、SAS/IML ではなく SAS/Base について話していると思います。SAS/IML は基本的に R に似ており、同じ種類の操作を同じ方法で利用できます。

SAS/Base は、マトリックス言語よりもデータベース言語に似ています (ただし、両方の要素がいくつかあり、OOP 言語の要素もいくつかあり、フル機能の関数型プログラミング言語でもあります)。

その結果、同じ目標を達成するために、多少異なることを行うことになります。さらに、大規模なデータ テーブル内のデータを移動するにはコストがかかるため、同じ結果を得るために複数の方法が用意されています。必要な状況に適した方法を選択できます。

まず、一般的に、提案された方法でデータをマクロ変数に格納しないでください。これは悪いプログラミング手法であり、非効率的です (既にお気づきのとおり)。SAS データセットは、データを格納するために存在します。SAS マクロ変数は、プログラミング タスクを簡素化し、コードを実行するのに役立ちます。

Base SAS では、上記のようにデータセット "b" を簡単に作成できます。

data b;
set a;
keep v2;
run;

これにより、A と同じ行で新しいデータセットが作成されますが、2 番目の列のみが作成されます。KEEP と DROP を使用すると、データセットに含まれる列を制御できます。

ただし、データの変更を計画していない限り、このデータセットにはほとんど意味がありません。結局のところ、それには A と同じ情報が含まれていますが、それより少ないだけです。したがって、たとえば、b を作成するのではなく、V2 を別のデータセットにマージする場合は、単純に A でデータセット オプションを使用できます。

data c;
merge z a(keep=v2);
by id;
run;

(注: A と Z を結合する何らかの形式の ID 変数を前提としています。) このマージにより、v2 列が z に結合され、新しいデータセット c が作成されます。これは、2 つの行列を垂直方向に連結することと同じです (単純に連結すると 'by id;' の要件が取り除かれますが、データベースでは、順序が期待どおりになるとは限らないため、通常はそうしません)。

bを使用して何か他のことをする予定がある場合、それを作成および/または使用する方法は、その使用法によって異なります。format値のマッピング [つまり、1='Hello' 2='Goodbye'] を作成できるため、1 つのプログラミング ステートメントで 1 つの値を別の値に変換できます。ハッシュテーブルにロードできます。行に転置できます ( proc transpose)。詳細を入力すると、より具体的な回答を提供できます。

于 2013-03-27T06:54:01.587 に答える