SAS阵列计算行操作

时间:2015-08-21 16:52:04

标签: arrays sas

我有一个数据集,其中包含销售组织成员的贡献列表。我想最终得到的是以下信息:

每一天:

  • 整个团队的销售量。 (第一天200美元,第二天350美元......)
  • 该团队的指定子集(例如“Joe”......)已售出多少(Joe每天售出100美元,第二天售出200美元......)
  • 上述两项计算的差异(第一天为200美元至100美元,第二天为350美元至200美元......)
  • 当天贡献了多少人(第1天2人,第2天3人,第3天5人)
  • 我指定的子集当天贡献了多少(在这种情况下每天1次,因为Joe每天都在那里)

在下面的示例中,Joe是我指定的子集。我遇到的问题是指导SAS只总结Joe的贡献。我下面的方法有效,但只有乔是唯一的贡献者,如果他每天贡献。我基本上强迫他成为第一个入口,然后指向他。如果他有一天不在那里,或者我的子集有多个人,那就失败了。

以下是我一直在努力的尝试,但我认为我走的是错误的道路,因为当我添加更多人时,这将不够动态。例如,如果子集现在变为Joe和Sue ......计算仍将仅指向Joe。如果我指出前两个两个障碍物,它可能会从第一天意外地选择hal。有没有办法通过rom指定“只有添加Amount列,如果它旁边的名字是Joe或Sue?帮助!

*declare team;
/*%let team=('joe','sue');*/
%let team=('joe');

*input data;
data have;
    input day name $ amount;
cards;
1 hal 100
1 joe 100
2 joe 80
2 sue 70
2 jim 200
3 joe 50
3 sue 100
3 ted 200
3 tim 100
3 wen 5000
;
run;

*getting my team to float to top of order list;
data have;
    set have;
    if name in &team. then order=1;
    else order=2;
run;

*order;
proc sort data=have;
    by day order name;
run;

*add running count by day;
data have;
    set have;
    by day;
    x+1;
    if first.day then x=1;
run;

*get number of people on team;
proc sql noprint;
    select count(distinct name) into :count
    from have 
    where name in &team.;
quit;

*get max of people per day;
proc sql noprint;
    select max(x) into :max_freq from have;
quit;

*pre transpose...set labels;
data have;
    set have;
    varname=cats('Name_',x);
    value=name;
    output;
    varname=cats('Amount_',x);
    value=amount;
    output;
    keep day value varname;
run;

*transpose;
proc transpose data=have out=have_transp(drop=_NAME_);
    by day;
    id varname;
    var value;
run;


data want;
    set have_transp;
    array Amount {*} Amount:;
    TOT_Amount=0;
    NUM_TOTAL_PEOPLE=0;
    do i=1 to dim(Amount);
        if Amount[i]>0
        then 
            do;
                TOT_Amount+Amount[i];
                NUM_TOTAL_PEOPLE+1;
            end;
    end;
    TEAM_CONTRIB=Amount_1;
    NON_TEAM_CONTRIB=TOT_Amount-TEAM_CONTRIB;

run;

其他一些事情:

  • 团队中的每个成员并不总是每天都在场
  • 总体团队和/或子集中有多少人可能有很多种可能性

1 个答案:

答案 0 :(得分:2)

这是一种使用proc的方法,它不使用数组。使用CLASS和TYPES语句时,Proc意味着默认计算不同级别的数据。然后可以将数据合并到适当的级别。在这个解决方案中,群体/子集中有多少人或每个人每天都在场,这并不重要。

/*Subset group*/
data subteam;
input name $;
cards;
joe
sue
;
run;

/*Sample data*/
data have;
    input day name $ amount;
cards;
1 hal 100
1 joe 100
2 joe 80
2 sue 70
2 jim 200
3 joe 50
3 sue 100
3 ted 200
3 tim 100
3 wen 5000
;
run;

*Set group variable for subset team;
data have;
set have;
group=0;
run;

*Set group variable=1 to subset;
proc sql;
update have
set group=1 
where name in (select name from subteam);
quit;

*Calculate sums;
proc means data=have;
class day group;
types day day*group;
var amount;
output out=want1 sum=total n=count;
run;

*Reformat into desired format;
data want2;
merge want1 (where=(group=.) rename=(total=total_overall count=count_overall))
      want1 (where=(group=1) rename=(total=total_group count=count_group));
by day;

run;