函数 LAG<n> 中的动态 n(变量)SAS_part2
Dynamic n in function LAG<n> (variable) SAS_part2
你知道如何在函数 LAGn(variable) 中使用 n 来引用程序中的另一个宏变量-> 在我的例子中是 max by V1?
data example1;
input V1 value V2;
datalines;
a 1.0 2.0
a 1.0 1.0
a 1.0 1.0
b 1.0 1.0
b 1.0 1.0
;
proc sql;
select max(V2) format = 1. into :n
from example1;
quit;
data example1;
set example1;
by V1;
lagval=lag&n(V2);
run;
来自 user667489 的代码,适用于一列。 现在n由V1改变。
我预计:
MAX LAG
a 1.0 2.0 2 .
a 1.0 1.0 2 .
a 1.0 1.0 2 2
b 1.0 1.0 1 .
b 1.0 1.0 1 1
;
LAG<n>
函数是一个固定深度的就地堆栈,特定于它的代码使用位置,因此特定于调用时的步进状态。堆栈很深,不能在运行时动态更改。
可以使用散列对象在 SAS DATA 步中实现动态滞后。双 DOW 技术允许测量一个组,然后对其进行操作。
示例代码
此示例使用定义了一个 hash
对象,该对象在一个组中维护一堆值。第一个 DOW 循环计算成为动态堆栈高度的字段的最大值。第二个 DOW 循环迭代组并检索滞后值,同时还为未来的项目滞后建立堆栈。
* some faux data;
data have (keep=group value duration);
do group = 1 to 10;
limit = ceil(4 * ranuni(6));
put group= limit=;
do _n_ = 1 to 8 + 10*ranuni(123);
value = group*10 + _n_;
duration = 1 + floor(limit*ranuni(123));
output;
end;
end;
run;
* dynamic lag provided via hash;
data want;
if _n_ = 1 then do;
retain index lag_value .;
declare hash lag_stack();
lag_stack.defineKey('index');
lag_stack.defineData('lag_value');
lag_stack.defineDone();
end;
do _n_ = 1 by 1 until (last.group);
set have;
by group;
max_duration = max(max_duration, duration);
end;
* max_duration within group is the lag lag_stack height;
* pre-fill missings ;
do index = 1-max_duration to 0;
lag_stack.replace(key: index, data: .);
end;
do _n_ = 1 to _n_;
set have;
lag_stack.replace(key: _n_, data: value);
lag_stack.find(key: _n_ - max_duration);
output;
end;
drop index;
run;
另一种技术将涉及固定长度的环形数组而不是散列堆栈,但您需要在使用数组对 DATA 步进行编码之前计算所有组的最大滞后。
忘掉 LAG()。只需添加一个计数器变量并加入它即可。
让我们修正您的示例数据步骤,使其正常工作。
data example1;
input V1 $ value V2;
datalines;
a 1 2
a 1 1
a 1 1
b 1 1
b 1 1
;
现在在每个 BY 组中添加一个唯一的行 ID。
data step1;
set example1;
by v1;
if first.v1 then row=0;
row+1;
run;
现在只需将此数据集与其自身连接起来即可。
proc sql ;
create table want as
select a.*,b.v2 as lag_v2
from (select *,max(v2) as max_v2 from step1 group by v1) a
left join step1 b
on a.v1= b.v1 and a.row = b.row + a.max_v2
;
quit;
结果:
Obs V1 value V2 row max_v2 lag_v2
1 a 1 2 1 2 .
2 a 1 1 2 2 .
3 a 1 1 3 2 2
4 b 1 1 1 1 .
5 b 1 1 2 1 1
希望你的实际用例比这个例子更有意义。
你知道如何在函数 LAGn(variable) 中使用 n 来引用程序中的另一个宏变量-> 在我的例子中是 max by V1?
data example1;
input V1 value V2;
datalines;
a 1.0 2.0
a 1.0 1.0
a 1.0 1.0
b 1.0 1.0
b 1.0 1.0
;
proc sql;
select max(V2) format = 1. into :n
from example1;
quit;
data example1;
set example1;
by V1;
lagval=lag&n(V2);
run;
来自 user667489 的代码,适用于一列。 现在n由V1改变。 我预计:
MAX LAG
a 1.0 2.0 2 .
a 1.0 1.0 2 .
a 1.0 1.0 2 2
b 1.0 1.0 1 .
b 1.0 1.0 1 1
;
LAG<n>
函数是一个固定深度的就地堆栈,特定于它的代码使用位置,因此特定于调用时的步进状态。堆栈很深,不能在运行时动态更改。
可以使用散列对象在 SAS DATA 步中实现动态滞后。双 DOW 技术允许测量一个组,然后对其进行操作。
示例代码
此示例使用定义了一个 hash
对象,该对象在一个组中维护一堆值。第一个 DOW 循环计算成为动态堆栈高度的字段的最大值。第二个 DOW 循环迭代组并检索滞后值,同时还为未来的项目滞后建立堆栈。
* some faux data;
data have (keep=group value duration);
do group = 1 to 10;
limit = ceil(4 * ranuni(6));
put group= limit=;
do _n_ = 1 to 8 + 10*ranuni(123);
value = group*10 + _n_;
duration = 1 + floor(limit*ranuni(123));
output;
end;
end;
run;
* dynamic lag provided via hash;
data want;
if _n_ = 1 then do;
retain index lag_value .;
declare hash lag_stack();
lag_stack.defineKey('index');
lag_stack.defineData('lag_value');
lag_stack.defineDone();
end;
do _n_ = 1 by 1 until (last.group);
set have;
by group;
max_duration = max(max_duration, duration);
end;
* max_duration within group is the lag lag_stack height;
* pre-fill missings ;
do index = 1-max_duration to 0;
lag_stack.replace(key: index, data: .);
end;
do _n_ = 1 to _n_;
set have;
lag_stack.replace(key: _n_, data: value);
lag_stack.find(key: _n_ - max_duration);
output;
end;
drop index;
run;
另一种技术将涉及固定长度的环形数组而不是散列堆栈,但您需要在使用数组对 DATA 步进行编码之前计算所有组的最大滞后。
忘掉 LAG()。只需添加一个计数器变量并加入它即可。
让我们修正您的示例数据步骤,使其正常工作。
data example1;
input V1 $ value V2;
datalines;
a 1 2
a 1 1
a 1 1
b 1 1
b 1 1
;
现在在每个 BY 组中添加一个唯一的行 ID。
data step1;
set example1;
by v1;
if first.v1 then row=0;
row+1;
run;
现在只需将此数据集与其自身连接起来即可。
proc sql ;
create table want as
select a.*,b.v2 as lag_v2
from (select *,max(v2) as max_v2 from step1 group by v1) a
left join step1 b
on a.v1= b.v1 and a.row = b.row + a.max_v2
;
quit;
结果:
Obs V1 value V2 row max_v2 lag_v2
1 a 1 2 1 2 .
2 a 1 1 2 2 .
3 a 1 1 3 2 2
4 b 1 1 1 1 .
5 b 1 1 2 1 1
希望你的实际用例比这个例子更有意义。