重新上传,因为我的上一篇文章存在一些问题,而且我不知道我们应该发布样本数据。我对SAS很新,我有一个问题,我知道如何在Excel中解决,而不是SAS。但是,数据集太大而无法在Excel中合理使用。
我有四个变量:id,year_start,groupname,test_score。
示例数据:
id year_start group_name test_score
1 19931231 Red 90
1 19941230 Red 89
1 19951231 Red 91
1 19961231 Red 92
2 19930630 Red 85
2 19940629 Red 87
2 19950630 Red 95
3 19950931 Blue 90
3 19960931 Blue 90
4 19930331 Red 95
4 19940331 Red 97
4 19950330 Red 98
4 19960331 Red 95
5 19931231 Red 96
5 19941231 Red 97
我的目标是每年通过test_score获得排名列表(小数)。我希望能够使用PROC RANK FRACTION实现这一目标。此函数将通过test_score计算顺序(最高为1,第二高为2,依此类推),然后除以观察总数以提供小数等级。不幸的是,year_start在行与行之间存在很大差异。对于每个id / year组合,我想从年开始执行一年的回顾,并将该观察与所有其他在该一年范围内具有year_start的id进行排名。我对按日历年比较不感兴趣,每个id的等级应该相对于它自己的year_start。添加另一级别的复杂功能,我希望这个级别由groupname执行。
如果有人拥有SQL解决方案,PROC SQL就完全没问了。
使用上述数据,排名如下:
id year_start group_name test_score rank
1 19931231 Red 90 0.75
1 19941230 Red 89 0.8
1 19951231 Red 91 1
1 19961231 Red 92 1
2 19930630 Red 85 1
2 19940629 Red 87 0.8
2 19950630 Red 95 0.75
3 19950931 Blue 90 1
3 19960931 Blue 90 1
4 19930331 Red 95 1
4 19940331 Red 97 0.2
4 19950330 Red 98 0.2
4 19960331 Red 95 0.333
5 19931231 Red 96 0.25
5 19941231 Red 97 0.667
为了计算第1行的等级,
在Excel中,此变量的公式看起来像这样。假设公式适用于第1行,有100行。 id = A,year_start = B,groupname = C,test_score = D:
=(1+countifs(D1:D100,">"&D1,
B1:B100,"<="&B1,
B1:B100,">"&B1-365.25,
C1:C100, C1))/
countifs(B1:B100,"<="&B1,
B1:B100,">"&B1-365.25,
C1:C100, C1)
非常感谢你的帮助!
ahammond428
答案 0 :(得分:1)
如果我正确地阅读它,你的例子是不正确的,所以很难确切知道你想要做什么。但请尝试以下操作,看看它是否有效。您可能需要调整不等式是否可以打开或关闭,具体取决于您是否要在该日期中包含一年。请注意,您的year_start列需要以SAS日期格式导入才能生效。否则你可以用输入(year_start,yymmdd8。)来改变它。
proc sql;
select distinct
a.id,
a.year_start,
a.group_name,
a.test_score,
1+sum(case when b.test_score > a.test_score then 1 else 0 end) as rank_num,
count(b.id) as rank_denom,
calculated rank_num / calculated rank_denom as rank
from testdata a left join testdata b
on a.group_name = b.group_name
and intnx('year',a.year_start,-1,'s') le b.year_start le a.year_start
group by a.id, a.year_start, a.group_name, a.test_score
order by id, year_start;
quit;
请注意,我将9/31的日期更改为9/30(因为没有9/31),但仅剩下3月30日,6月29日和12月30日,因为这可能是预期的,尽管另一个约会似乎是四分之一。
答案 1 :(得分:0)
考虑SQL中的相关计数子查询:
数据
data ranktable;
infile datalines missover;
input id year_start group_name $ test_score;
datalines;
1 19931231 Red 90
1 19941230 Red 89
1 19951231 Red 91
1 19961231 Red 92
2 19930630 Red 85
2 19940629 Red 87
2 19950630 Red 95
3 19950930 Blue 90
3 19960930 Blue 90
4 19930331 Red 95
4 19940331 Red 97
4 19950330 Red 98
4 19960331 Red 95
5 19931231 Red 96
5 19941231 Red 97
;
run;
data ranktable;
set ranktable;
format year_start date9.;
year_start = input(put(year_start,z8.),yymmdd8.);
run;
PROC SQL
审核中包含的其他字段
proc sql;
select r.id, r.year_start, r.group_name, r.test_score,
put(intnx('year', r.year_start, -1, 's'), yymmdd10.) as year_ago,
(select count(*) from ranktable sub
where sub.test_score >= r.test_score
and sub.group_name = r.group_name
and sub.year_start <= r.year_start
and sub.year_start >= intnx('year', r.year_start, -1, 's')) as num_rank,
(select count(*) from ranktable sub
where sub.group_name = r.group_name
and sub.year_start <= r.year_start
and sub.year_start >= intnx('year', r.year_start, -1, 's')) as denom_rank,
calculated num_rank / calculated denom_rank as rank
from ranktable r;
run;
<强>输出强>
您会注意到您的预期结果之间存在细微差异,这可能是由于您申请所有年份的季度日(365.25),因为SAS intnx
需要一整天的日历年随着每年的变化