SAS创建动态间隔

时间:2012-06-16 23:37:28

标签: sas

这有点复杂(至少对我而言)。

以下是我必须做的事情: 假设我有以下数据集:

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

假设我有一个断点,我想在我的数据集中创建一个间隔。例如,让我的断点= 200交易量。

我想要的是创建一个ID列并为每个断点= 200记录一个ID变量= 1,2,3,...当你对每个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)

正如你所看到的,我不得不“分解”一些行(比如第二行,例如,我将200分成两个100卷),以便在所有ID中获得总和200的总和值。

2 个答案:

答案 0 :(得分: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;

我用你的数据集对它进行了测试,看起来是正确的,但我会仔细检查几个案例以确认它是否正常。

答案 1 :(得分:1)

如果您有一个表示“买入”或“卖出”的变量,那么您可以试试这个。假设这个变量叫做type,取值为'B'或'S'。使用这种方法的一个优点是,如果有的话,更容易处理'by-groups'。

%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;