2

これはやや複雑です (少なくとも私にとっては)。

これが私がしなければならないことです: 次のデータセットがあるとします:

date    price   volume
02-Sep  40  100
03-Sep  45  200
04-Sep  46  150
05-Sep  43  300

データセットに間隔を作成したいブレークポイントがあるとします。たとえば、ブレークポイント = 200 ボリューム トランザクションとします。

私が望むのは、ID 列を作成し、ブレークポイントごとに ID 変数 =1,2,3,... を記録することです = 200.ID ごとのすべてのボリュームを合計すると、値はすべての ID 変数で一定でなければなりません。

上記の例を使用すると、最終的なデータセットは次のようになります。

date    price   volume  id
02-Sep  40  100 1
03-Sep  45  100 1
03-Sep  45  100 2
04-Sep  46  100 2
04-Sep  46  50  3
05-Sep  43  150 3
05-Sep  43  150 4 

(最後の行はいくつかの値を見逃す可能性がありますが、それは問題ありません。最後の ID を追い出します)

ご覧のとおり、すべての ID のボリュームの合計 200 を一定の値にするために、いくつかの行を「分解」する必要がありました (たとえば、2 行目のように、200 を 2 つの 100 ボリュームに分割します)。

4

2 に答える 2

4

流動毒性VPIN計算のためにボリュームバケットを実行しているようです。私はこれがうまくいくと思います:

%let bucketsize = 200;

data buckets(drop=bucket volume rename=(vol=volume));
    set tmp;
    retain bucket &bucketsize id 1;

    do until(volume=0);
        vol=min(volume,bucket);
        output;
        volume=volume-vol;
        bucket=bucket-vol;
        if bucket=0 then do;
            bucket=&bucketsize;
            id=id+1;
        end;
    end;
run;

私はあなたのデータセットでこれをテストしました、そしてそれは正しく見えます、しかし私はそれが正しく働くことを確認するためにいくつかのケースを注意深くチェックします。

于 2012-06-17T00:42:18.070 に答える
1

「購入」または「販売」を示す変数がある場合は、これを試すことができます。この変数がtypeと呼ばれ、値「B」または「S」をとるとします。この方法を使用する利点の1つは、「グループごと」の処理が簡単になることです。

%let bucketsize = 200;

data tmp2;
  set tmp;
  retain volsumb idb volusums ids;

  /* Initialize. */
  volusumb = 0; idb = 1; volsums = 0; ids = 1;

  /* Store the current total for each type. */
  if type = 'B' then volsumb = volsumb + volume;
  else if type = 'S' then volsums = volsums + volume;

  /* If the total has reached 200, then reset and increment id. */
  /* You have not given the algorithm if the volume exceeds 200, for example the first two values are 150 and 75. */
  if volsumb = &bucketsize then do; idb = idb + 1; volsumb = 0; end;
  if volsums = &bucketsize then do; ids = ids + 1; volsums = 0; end;

  drop volsumb volsums;
run;
于 2012-06-18T15:47:35.797 に答える