Использование оператора сохранения для математических операций в SAS - PullRequest
1 голос
/ 19 июня 2009

У меня есть набор данных с 4 наблюдениями (строками) на человека.

Я хочу создать три новые переменные, которые вычисляют разницу между второй и первой, третьей и второй, а также четвертой и третьей строками.

Я думаю, что retain может это сделать, но я не уверен, как.

Или мне нужен массив?

Спасибо!

Ответы [ 5 ]

1 голос
/ 09 июля 2009

Почему бы не использовать функцию Lag.

data test;  input person var;
cards; 
1 5
1 10
1 12
1 20
2 1
2 3
2 5
2 90
run;

data test;  set test;
by person; 
LagVar=Lag(Var);
difference=var-Lagvar;
if first.person then difference=.;
run;
1 голос
/ 19 июня 2009

data test;
  input person var;
  datalines;
1 5
1 10
1 12
1 20
2 1
2 3
2 5
2 90
;
run;

data test;
  set test;
  by person notsorted;
  retain pos;
  array diffs{*} diff0-diff3;
  retain diff0-diff3;
  if first.person then do;
    pos = 0;
  end;
  pos + 1;
  diffs{pos} = dif(var);
  if last.person then output;
  drop var diff0 pos;
run;

0 голосов
/ 29 сентября 2009
data output_data;   
   retain count previous_value diff1 diff2 diff3;  
   set data input_data    
     by person;  
   if first.person then do;   
     count = 0;  
   end;  
   else do;  
     count = count + 1;  
     if count = 1 then diff1 = abs(value - previous_value);  
     if count = 2 then diff2 = abs(value - previous_value);  
     if count = 3 then do;   
       diff3 = abs(value - previous_value);   
       output output_data;   
     end;  
   end;  
   previous_value = value;  
run;
0 голосов
/ 20 августа 2009

Почему бы вместо этого не использовать функцию dif ()?

/* test data */
data one;
  do id = 1 to 2;
    do v = 1 to 4 by 1;
      output;
    end;
  end;
run;
/* check */
proc print data=one;
run;
/* on lst
Obs    id    v

 1      1    1
 2      1    2
 3      1    3
 4      1    4
 5      2    1
 6      2    2
 7      2    3
 8      2    4
*/

/* now create diff within id */
data two;
  set one;
  by id notsorted; /* assuming already in order */
  dif = ifn(first.id, ., dif(v));
run;
proc print data=two;
run;
/* on lst
Obs    id    v    dif
 1      1    1     .
 2      1    2     1
 3      1    3     1
 4      1    4     1
 5      2    1     .
 6      2    2     1
 7      2    3     1
 8      2    4     1
*/
0 голосов
/ 23 июня 2009

Альтернативный подход без массивов .

/*-- Data from simonn's answer --*/
data SO1019005;
  input person var;
  datalines;
1 5
1 10
1 12
1 20
2 1
2 3
2 5
2 90
;
run;

/*-- Why not just do a transpose? --*/
proc transpose data=SO1019005 out=NewData;
by person;
run;

/*-- Now calculate your new vars --*/
data NewDataWithVars;
set NewData;

NewVar1 = Col2 - Col1;
NewVar2 = Col3 - Col2;
Newvar3 = Col4 - Col3;

run;
...