Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Loops SAS:对除一个以外的所有值求和_Loops_Sum_Sas - Fatal编程技术网

Loops SAS:对除一个以外的所有值求和

Loops SAS:对除一个以外的所有值求和,loops,sum,sas,Loops,Sum,Sas,我在SAS工作,我试图总结所有的观察结果,每次漏掉一个。 例如,如果我有: Count Name Grade 1 Sam 90 2 Adam 100 3 John 80 4 Max 60 5 Andrea 70 我想为Sam输出一个值,它是除他自己之外的所有等级的总和,为Adam输出一个值,它是除他自己之外的所有等级的总和,以此类推 有什么想法吗?谢

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

Count    Name      Grade
1        Sam        90
2        Adam       100
3        John       80
4        Max        60
5        Andrea     70
我想为Sam输出一个值,它是除他自己之外的所有等级的总和,为Adam输出一个值,它是除他自己之外的所有等级的总和,以此类推


有什么想法吗?谢谢

此解决方案执行对起始数据集的每次观察,然后循环通过相同的数据集,汇总具有不同名称的任何记录的等级值,因此从“Sam”开始,我们仅在找到非“Sam”名称时添加
oth_g
变量:

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; 数据需求; 集有; oth_g=0; i=1到n; 集有 (保持=名称等级重命名=(名称=名称\循环等级=等级\循环)) nobs=n点=i; 如果name^=name_循环,则oth_g+grade_循环; 结束; 删除等级\回路名称\回路输入; 跑
虽然还没有测试过,但上面的方法应该可以工作。它创建一个新的数据集temp,该数据集包含所有成绩的总和,并将其合并回来,以创建一个新表,其中所有成绩的总和减去当前学生的成绩作为sum\u other\u成绩。

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


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

您可以在单个PROC sql中执行此操作,使用关键字computed:

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;

这是对上面提供的答案@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的查询所做的那样)


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

谢谢。我尝试过这个解决方案,但它给我的Sam值为0,给其他所有人的值都是一样的。@Deb,你遗漏了一些东西;这与我运行它时宣传的完全一样。我已经在新的SAS Studio Online产品中对其进行了测试。在复制时请小心e行围绕第二个set语句进行反馈。为了可读性,我只在这里添加了一些额外的内容。谢谢,这是一个很好的解决方案,因为这样做不需要消息
注意:查询需要将摘要统计信息与原始数据重新合并。
请查看我对@Reese下面答案的轻微修改。每当我看到日志中是否有消息它几乎总是意味着我在我的
group by
select
子句中犯了错误。我认为,如果使用
having
子句,日志消息并不一定意味着犯了错误。尽管它在SAS中的使用通常不是有效的ANSI SQL(根据我的经验),这是
proc sql
的一个方便功能。它可以返回所需的结果,是的,但即使返回了,您为什么要这样做?同样的结果可以通过重写代码来实现,这样代码更可读、更高效,并且与其他语言和数据库兼容!我个人认为SAS不应该允许这样做必须是有效的语法。
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.