对拆分为两列的行求和
sum over rows split between two columns
我的数据看起来像这样,我不知道如何获取列 "want"。不幸的是,我已经尝试了 retain、lag 和 sum 函数的各种组合,但没有成功。
month quantity1 quantity2 want
1 a x x+sum(b to l)
2 b y sum(x to y)+sum(c to l)
3 c z sum(x to z)+sum(d to l)
4 d
5 e
6 f
7 g
8 h
9 i
10 j
11 k
12 l
感谢您对此事的任何帮助
您也许可以一步完成此操作,但以下步骤会分两步产生所需的结果。第一步是计算相关 quantity1
值的总和,第二步是将它们添加到相关 quantity2
值的总和:
data temp;
input month qty1 qty2;
datalines;
1 1 100
2 1 100
3 1 100
4 1 .
5 1 .
6 1 .
7 1 .
8 1 .
9 1 .
10 1 .
11 1 .
12 1 .
;
run;
proc sql;
create table qty1_sums as select distinct
a.*, sum(b.qty1) as qty1_sums
from temp as a
left join temp as b
on a.month < b.month
group by a.month;
create table want as select distinct
a.*,
case when not missing(a.qty2) then sum(a.qty1_sums, sum(b.qty2)) end as want
from qty1_sums as a
left join temp as b
on a.month >= b.month
group by a.month;
quit;
听起来像 'rolling 12 months sum'。如果是这样,使用不同的数据结构(不是 2 个变量,而是 24 行 1 个变量)更容易;那么您拥有所有 ETS 工具,或者在 SQL 或 SAS 数据步骤中的一个简单过程。
如果您不能't/won重组您的数据,那么您可以通过将数据加载到临时数组(或散列 table 但数组对于新手来说更简单)来实现。这使您可以直接访问整个内容。示例:
data have;
do month = 1 to 12;
q_2014 = rand('Uniform')*10+500+month*5;
q_2015 = rand('Uniform')*10+550+month*5;
output;
end;
run;
data want;
array q2014[12] _temporary_; *temporary array to hold data;
array q2015[12] _temporary_;
if _n_=1 then do; *load data into temporary arrays;
do _n = 1 to n_data;
set have point=_n nobs=n_data;
q2014[_n] = q_2014;
q2015[_n] = q_2015;
end;
end;
set have;
do _i = 1 to _n_; *grab the this_year data;
q_rolling12 = sum(q_rolling12,q2015[_i]);
end;
do _j = _n_+1 to n_data;
q_rolling12 = sum(q_rolling12,q2014[_j]);*grab the last_year data;
end;
run;
对quantity1进行求和,然后将值存入宏变量,很方便。使用多余的数据示例:
proc sql;
select sum(qty1) into:sum_qty1 from temp;
quit;
data want;
set temp;
value1+qty1;
value2+qty2;
want=value2+&sum_qty1-value1;
if missing(qty2) then want=.;
drop value:;
run;
我的数据看起来像这样,我不知道如何获取列 "want"。不幸的是,我已经尝试了 retain、lag 和 sum 函数的各种组合,但没有成功。
month quantity1 quantity2 want
1 a x x+sum(b to l)
2 b y sum(x to y)+sum(c to l)
3 c z sum(x to z)+sum(d to l)
4 d
5 e
6 f
7 g
8 h
9 i
10 j
11 k
12 l
感谢您对此事的任何帮助
您也许可以一步完成此操作,但以下步骤会分两步产生所需的结果。第一步是计算相关 quantity1
值的总和,第二步是将它们添加到相关 quantity2
值的总和:
data temp;
input month qty1 qty2;
datalines;
1 1 100
2 1 100
3 1 100
4 1 .
5 1 .
6 1 .
7 1 .
8 1 .
9 1 .
10 1 .
11 1 .
12 1 .
;
run;
proc sql;
create table qty1_sums as select distinct
a.*, sum(b.qty1) as qty1_sums
from temp as a
left join temp as b
on a.month < b.month
group by a.month;
create table want as select distinct
a.*,
case when not missing(a.qty2) then sum(a.qty1_sums, sum(b.qty2)) end as want
from qty1_sums as a
left join temp as b
on a.month >= b.month
group by a.month;
quit;
听起来像 'rolling 12 months sum'。如果是这样,使用不同的数据结构(不是 2 个变量,而是 24 行 1 个变量)更容易;那么您拥有所有 ETS 工具,或者在 SQL 或 SAS 数据步骤中的一个简单过程。
如果您不能't/won重组您的数据,那么您可以通过将数据加载到临时数组(或散列 table 但数组对于新手来说更简单)来实现。这使您可以直接访问整个内容。示例:
data have;
do month = 1 to 12;
q_2014 = rand('Uniform')*10+500+month*5;
q_2015 = rand('Uniform')*10+550+month*5;
output;
end;
run;
data want;
array q2014[12] _temporary_; *temporary array to hold data;
array q2015[12] _temporary_;
if _n_=1 then do; *load data into temporary arrays;
do _n = 1 to n_data;
set have point=_n nobs=n_data;
q2014[_n] = q_2014;
q2015[_n] = q_2015;
end;
end;
set have;
do _i = 1 to _n_; *grab the this_year data;
q_rolling12 = sum(q_rolling12,q2015[_i]);
end;
do _j = _n_+1 to n_data;
q_rolling12 = sum(q_rolling12,q2014[_j]);*grab the last_year data;
end;
run;
对quantity1进行求和,然后将值存入宏变量,很方便。使用多余的数据示例:
proc sql;
select sum(qty1) into:sum_qty1 from temp;
quit;
data want;
set temp;
value1+qty1;
value2+qty2;
want=value2+&sum_qty1-value1;
if missing(qty2) then want=.;
drop value:;
run;