SAS中文论坛

标题: 问题请假,谢谢! [打印本页]

作者: shiyiming    时间: 2008-2-21 14:24
标题: 问题请假,谢谢!
在一个数据集中,包括不同运动员的不同项目的成绩
且同一运动员有多条观测,就好比有多个裁判积分

请问如何能用简单的程序算出各个运动员的各项成绩,每个裁判打分是不是一样的
如果有不一样,是哪个运动员哪个项目
由于运动员很多,而且每人的项目也很多
最好不要用各个变量手工输入的方法
作者: shiyiming    时间: 2008-2-21 16:06
标题: Re: 问题请假,谢谢!
请给出数据集的样子,并且说清楚需要计算什么。
比如 DATA有哪几个变量,要计算什么统计量,这个应该不难
作者: shiyiming    时间: 2008-2-21 16:48
标题: Re: 问题请假,谢谢!
比如这样一个数据集体,当然实际数据集更多观测更多变量
姓名        a        b        c        d        ……
XX        1        2        3        4        ……
XX        1        2        3        4        ……
XX        2        2        3        4        ……
YY        1        1        1        1        ……
YY        1        1        1        2        ……
ZZZ        3        3        3        3        ……
ZZZ        3        3        3        3        ……
ZZZ        3        3        3        3        ……
ZZZ        3        3        3        3        ……

最好要得到的结果如下:
名        a        b        c        d        ……
XX,        N,        ,        ,        ,       
YY,        ,        ,        ,        N,       
ZZZ,        ,        ,        ,        ,       
即是说XXX的a项目有不同,YYY的d项目有不同,zzz的各项数据相同
注意:XX、YY、ZZZ的观测数不一定相等,就是记录条数不等

表格提交之后串位了,不好意思,结果中的数据
XX的N对应在a的一列,YY的N对应在d的一列
作者: shiyiming    时间: 2008-2-21 17:56
标题: Re: 问题请假,谢谢!
先贴一个比较笨的办法,就是要把所有的项目都得输入一遍,
proc sql;
   select Name, count(unique a) as NumA, count(unique b) as NumB, count(unique c) as NumC, count(unique d) as NumD
   from a
   group by name
   having NumA>1 or NumB>1 or NumC>1 or NumD>1;
quit;
作者: shiyiming    时间: 2008-2-21 20:53
标题: Re: 问题请假,谢谢!
这个程序果然好用,虽然还必须用一个一个输入变量名
但是比我自己想的笨办法好多了
谢谢哦!!
作者: shiyiming    时间: 2008-2-21 22:04
标题: Re: 问题请假,谢谢!
[code:3stqdlby]
/*思路1:取出每个运动员每个项目的最高得分和最低得分,如果最高分=最低分,即:极差=0,那么所有裁判的打分相同,否则,至少有一个裁判的打分与其他不一样*/
proc means data=a nway noprint;
        var a c b d;
        class name;
        output out=aa(drop=_type_ _freq_) range(a b c d)=r_a r_b r_c r_d;
run;
data result(drop=r_a--r_d) ;
        set aa;
        if r_a then a='N';
        else a='Y';
        if r_b then b='N';
        else b='Y';
        if r_c then c='N';
        else c='Y';
        if r_d then d='N';
        else d='Y';
run;

/*思路2:就是搂主的叙述*/
proc sort data=a out=aa noduprecs noequals;
        by name;
run;
data result(rename=(r_a=a r_b=b r_c=c r_d=d));
        set aa;
        by name;
        retain tmp_a tmp_b tmp_c tmp_d;
        retain r_a r_b r_c r_d;
        if first.name then do;
                tmp_a=a;tmp_b=b;tmp_c=c;tmp_d=d;
                r_a='Y';r_b='Y';r_c='Y';r_d='Y';
        end;
        if a^=tmp_a then r_a='N';
        if b^=tmp_b then r_b='N';
        if c^=tmp_c then r_c='N';
        if d^=tmp_d then r_d='N';
        if last.name;
        drop a--d tmp_a--tmp_d;
run;

[/code:3stqdlby]
作者: shiyiming    时间: 2008-2-22 09:07
标题: to byes
我的思路和“思路2”相同,应该是楼主叙述的常规思路的实现。

“思路1”的确更好,赞一个!
作者: shiyiming    时间: 2008-2-22 09:49
标题: Re: 问题请假,谢谢!
这两个思路都管用,不错,谢谢哦!

然后如果变量N多,且变量名没有规律的
有没有不用一个一个变量名输入的方法!
作者: shiyiming    时间: 2008-2-22 13:13
标题: Re: 问题请假,谢谢!
[code:31ounr0f]data aa;
input name $ a  b c d ;
cards;
XX 1 2 3 4
XX 1 2 3 4
XX 2 2 3 4
YY 1 1 1 1
YY 1 1 1 2
ZZZ 3 3 3 3
ZZZ 3 3 3 3
ZZZ 3 3 3 3
ZZZ 3 3 3 3
;
proc sort;by name;run;
proc sql noprint;
select count(name) into :n from sashelp.vcolumn
where libname='WORK' and memname='AA' and type='num';
select name into :name separated by ' ' from sashelp.vcolumn
where libname='WORK' and memname='AA' and type='num';
quit;

data bb(drop=&name i x);
set aa;by name;
array aa _numeric_;
array bb(&n);
do i=1 to  dim(aa);
x=lag(aa(i));
if aa(i)-x=0 then aa(i)=.;
if first.name then aa(i)=.;
bb(i)=aa(i);
end;
run;

data cc(keep=name &name);
set bb;by name;
array aa _numeric_;
array bb(&n) $ &name;
do i=1 to &n;
y=lag(aa(i));
aa(i)=sum(y,aa(i));
if aa(i) ne . then bb(i)='N';
end;
if last.name;
run;
[/code:31ounr0f]
作者: shiyiming    时间: 2008-2-22 13:44
标题: Re: 问题请假,谢谢!
笨办法之完整版,中间的if条件比较罗嗦,也许可以做循环。不过我还没有实现:
data a;
input name $ a b c d;
cards;
XX 1 2 3 4
XX 1 2 3 4
XX 2 2 3 4
YY 1 1 1 1
YY 1 1 1 2
ZZ 3 3 3 3
ZZ 3 3 3 3
ZZ 3 3 3 3
ZZ 3 3 3 3
;
run;
proc sql;
create table b as
select Name, count(unique a) as A, count(unique b) as B, count(unique c) as C, count(unique d) as D
from a
group by name;
quit;
data c;
set b;
length sa sb sc sd total $20.;
if A>1 then sa='A';
if B>1 then sb='B';
if C>1 then sc='C';
if D>1 then sd='D';
total=trim(left(trim(left(sa))||trim(left(sb))||trim(left(sc))||trim(left(sd))));
keep name total;
run;
作者: shiyiming    时间: 2008-2-22 19:59
标题: Re: 问题请假,谢谢!
[quote="mymine":2x0joz73]然后如果变量N多,且变量名没有规律的
有没有不用一个一个变量名输入的方法![/quote:2x0joz73]
你仔细体会一下我的程序,答案就在里面!!!
可以的。
作者: shiyiming    时间: 2008-2-22 20:47
标题: Re: 问题请假,谢谢!
[code:3e2mueao]
/*假设你的第一个项目为a,最后一个项目为m,一共有50个项目*/

proc means data=a nway noprint;
   var a--m;
   class name;
   output out=aa(drop=_type_ _freq_) range=r1-r50;
run;
data result(drop=r1-r50 i) ;
   set aa;
   array r{50} r1-r50;
   array v{50} $;
   do i=1 to dim(r);
   if r(i) then v(i)='N';
   else v(i)='Y';
   end;
run;

[/code:3e2mueao]

最后变量v1-v50分别记录了50个项目的情况,不知道能否满足你的要求
作者: shiyiming    时间: 2008-2-22 21:02
标题: to waterlwh
这个程序不错,不用逐个输入各个变量名
不过里面部分程序还看不懂呵呵
作者: shiyiming    时间: 2008-2-22 21:05
标题: to byes
谢谢哦,我在体会一下哈
作者: shiyiming    时间: 2008-2-22 21:20
标题: Re: 问题请假,谢谢!
如果你想把v1-v50还是用原来项目的变量名,请参考以下程序(还是以50个变量为例子):
[code:334jje0v]
data _null_;
        length val $800;
        dsid=open('a');
        array tt{50} $20;
        do i=1 to 50;
        tt(i)=varname(dsid,i+1);
        end;
        val=catx('',of tt1-tt4);
        call symput('val',trim(left(val)));
        rs=close(dsid);
run;
proc means data=a nway noprint;
   var &val;
   class name;
   output out=aa(drop=_type_ _freq_) range=r1-r50;
run;
data result(drop=r1-r50 i) ;
   set aa;
   array r{*} r1-r50;
   array v{*} $ &val;
   do i=1 to dim(r);
   if r(i) then v(i)='N';
   else v(i)='Y';
   end;
run;

[/code:334jje0v]
作者: shiyiming    时间: 2008-2-22 21:26
标题: Re: 程序有个bug,修改一下
[code:3695cfor]data aa;
input name $ a  b c d ;
cards;
XX 1 2 3 4
XX 1 2 3 4
XX 2 2 3 4
YY 1 1 1 1
YY 1 1 1 2
ZZZ 3 3 3 3
ZZZ 3 3 3 3
ZZZ 3 3 3 3
ZZZ 3 3 3 3
;
proc sort;by name;run;

proc sql noprint;
select count(name) into :n from sashelp.vcolumn
where libname='WORK' and memname='AA' and type='num';
select name into :name separated by ' ' from sashelp.vcolumn
where libname='WORK' and memname='AA' and type='num';
quit;

data bb(drop=&name i x);
set aa;by name;
array aa _numeric_;
array bb(&n);
do i=1 to  dim(aa);
x=lag(aa(i));
if aa(i)-x=0 then aa(i)=.;
if first.name then aa(i)=.;
bb(i)=aa(i);
end;
run;
run;

data cc(keep=name &name);
set bb;by name;
array aa _numeric_;
array bb(&n) $ &name;
retain &name;
do i=1 to &n;
if aa(i) ne . then bb(i)='N';
if first.name then bb(i)=' ';
end;
if last.name;
run;
[/code:3695cfor]
作者: shiyiming    时间: 2008-2-22 21:42
标题: Re: 问题请假,谢谢!
在byes的程序基础上用点macro,means在这儿确实可以减少步骤
[code:2d9g9f37]data aa;
input name $ a  b c d ;
cards;
XX 1 2 3 4
XX 1 2 3 4
XX 2 2 3 4
YY 1 1 1 1
YY 1 1 1 2
ZZZ 3 3 3 3
ZZZ 3 3 3 3
ZZZ 3 3 3 3
ZZZ 3 3 3 3
;
run;
proc sql noprint;
select put(count(name),5.-L)  into :n from sashelp.vcolumn
where libname='WORK' and memname='AA' and type='num';
select name into :name separated by ' ' from sashelp.vcolumn
where libname='WORK' and memname='AA' and type='num';
quit;

proc means data=aa nway noprint;
   var &name;
   class name;
   output out=bb(drop=_type_ _freq_) range=r1-r&n.;
run;


data result(drop=r1-r&n. i) ;
   set bb;
   array r{&n} r1-r&n.;
   array v{&n} $ &name;
   do i=1 to dim(r);
   if r(i) then v(i)='N';
   end;
run;
[/code:2d9g9f37]
作者: shiyiming    时间: 2008-2-25 17:17
标题: Re: 问题请假,谢谢!
[code:3b8kq62v]data ahuige;
  input name$  a$ b$ c$ d$;
  cards;
XX 1 2 3 4 ……
XX 1 2 3 4 ……
XX 2 2 3 4 ……
YY 1 1 1 1 ……
YY 1 1 1 2 ……
ZZZ 3 3 3 3 ……
ZZZ 3 3 3 3 ……
ZZZ 3 3 3 3 ……
ZZZ 3 3 3 3 ……
;
run;

proc sql;
  select compbl(', case when max('||name||')<>min('||name||') then "N" else "" end as '|| name) into :statement separated by ''
  from sashelp.vcolumn
  where memname='AHUIGE' and libname='WORK' and name<>'name'
  ;

proc sql;
  create table final as
  select name &statement
  from ahuige
  group by name
  ;[/code:3b8kq62v]
作者: shiyiming    时间: 2008-2-25 18:05
标题: Re: 问题请假,谢谢!
这个帖子可真够热的,已经演化成了高手飚程序了,连ahuige都出手了,呵呵呵。
作者: shiyiming    时间: 2008-2-26 13:04
标题: Re: 问题请假,谢谢!
谢谢大家的支持哈
我用了其中一两种程序实现了我的目的
后面的程序有些难度挺大的,还没有看明白
再学习学习,谢谢哦!




欢迎光临 SAS中文论坛 (https://mysas.net/forum/) Powered by Discuz! X3.2