SAS:除了一个以外的所有值的总和

时间:2014-11-28 17:05:33

标签: loops sum sas

我在SAS工作,我试图总结所有观察结果,每次遗漏一次。 例如,如果我有:

Count    Name      Grade
1        Sam        90
2        Adam       100
3        John       80
4        Max        60
5        Andrea     70

我想为Sam输出一个值,除了他自己的所有等级的总和,以及Adam的值,它是所有等级的总和,但是他自己的等等。

有什么想法吗?谢谢!

5 个答案:

答案 0 :(得分:4)

您可以使用关键字计算在单个proc sql中执行此操作:

data have;
input Count    Name  $    Grade;
datalines;
1        Sam        90
2        Adam       100
3        John       80
4        Max        60
5        Andrea     70
;;;;
run;

proc sql;
    create table want as
    select *, sum(grade) as all_grades, calculated all_grades-grade as minus_grade
    from have;
quit;

答案 1 :(得分:3)

proc sql;
create table temp as select
sum(grade) as all_grades
from orig_data;
quit;

proc sql;
create table temp2 as select
a.count,
a.name,
a.grade,
(b.all_grades-a.grade) as sum_other_grades
from orig_data a
left join temp b;
quit;

尚未测试过,但上述情况应该有效。它创建一个新的数据集临时表,其中包含所有成绩的总和,并将其合并,以创建一个新表,其中所有成绩的总和减去当前学生成绩为sum_other_grades。

答案 2 :(得分:3)

这里有一个近乎通过的解决方案(如果数据集适合读取缓冲区,它将与单程解决方案的速度大致相同)。我实际上在这里计算平均值而不仅仅是总和,因为我觉得这是一个更有趣的结果(总和当然是没有除法的平均值)。

data have;
input Count    Name  $    Grade;
datalines;
1        Sam        90
2        Adam       100
3        John       80
4        Max        60
5        Andrea     70
;;;;
run;

data want;
  retain grademean;
  if _n_=1 then do;
      do _n_ = 1 to nobs_have;
        set have(keep=grade) point=_n_ nobs=nobs_have;
        gradesum+grade;
      end;
      grademean=gradesum/nobs_have;
  end;
  set have;
  grade_noti = ((grademean*nobs_have)-grade)/(nobs_have-1);
run;

计算平均值,然后为每个记录减去记录对平均值的贡献。当您想要将记录与其他人群进行比较时,这是一种非常有用的统计测试技术,并且您有一个复杂的类组合,而您首先要做的是平均值。在这些情况下,首先使用PROC MEANS,然后将其合并,然后执行此减法。

答案 3 :(得分:1)

此解决方案执行每次观察您的起始数据集,然后循环遍历相同的数据集,总结具有不同名称的任何记录的成绩值,因此从' Sam'开始,我们只添加{{ 1}}变量,当我们找到名字不是' Sam':

data want;
  set have;
  oth_g=0;
  do i=1 to n;
    set have 
      (keep=name grade rename=(name=name_loop grade=grade_loop)) 
      nobs=n point=i;
    if name^=name_loop then oth_g+grade_loop;
  end;
  drop grade_loop name_loop i n;
run;

答案 4 :(得分:0)

这是对上面提供的@Reese答案的略微修改。

proc sql;
    create table want as
    select *,
           (select sum(grade) from have) as all_grades,
           calculated all_grades - grade as minus_grade
    from have;
quit;

我已经这样重新排列,以避免将以下信息打印到日志中:

NOTE: The query requires remerging summary statistics back with the original data.

如果您看到上述消息,几乎总是表示您犯了错误。如果你真的想要将原始数据重新汇总回原始数据,你应该明确地这样做(就像我上面通过重构@reese&#39的查询一样。

我个人认为重构版本也更容易理解。