我如何创建变量取决于其他观察

时间:2015-06-18 14:48:02

标签: sas proc-sql

我有一个大学数据,问题是找到相同的id,同一个course1和course2是否有下一学期。我有以下表格前4个变量:id,term,course1和course2。我正在尝试创建第五个变量' nextterm'。条款是这样的:201010-201020-201030-201110-201120-201130-201210,...等等。所以id = 21,course1和course2与201010和201020的MAT 51相同。所以201010将是,201020将是No。

  id    term    course1    course2                nextterm
  21    201010  MAT        41                        No
  21    201010  MAT        51                        Yes
  21    201020  MAT        51                        No
  21    201020  SPC        13                        No
  29    201130  pos        94                        Yes
  29    201210  pos        94                        No 

2 个答案:

答案 0 :(得分:0)

好的,这是更新的答案,它需要在某个级别对SQL有所了解,如果您的数据量不是太大,它就可以工作。请注意,我已将该术语转换为传入数据集中的数字,但也可以即时完成。如果你认为它运行速度太慢,那么我建议1.通过id,2中的降序来求助你的数据.DOW或Hash应该足够了。

    data have;
    input id    term    (course1    course2          ) (:$8.);
    cards;
  21    201010  MAT        41                  
  21    201010  MAT        51                  
  21    201020  MAT        51                  
  21    201020  SPC        13                  
  29    201120  pos        94                  
  29    201130  pos        94                  
;

   PROC SQL;
CREATE TABLE WANT AS
SELECT *, CASE WHEN EXISTS(SELECT * FROM HAVE WHERE ID=A.ID AND 
(INT(TERM/100) = INT(A.TERM/100) AND MOD(TERM,100)=MOD(A.TERM,100)+10 
 OR INT(TERM/100) = INT(A.TERM/100)+1 AND MOD(TERM,100)=MOD(A.TERM,100)-20) 
 AND CATS(A.COURSE1,A.COURSE2) = CATS(COURSE1,COURSE2)) 
                  THEN 'Yes' ELSE 'No' END AS NEXTTERM
FROM HAVE A;
QUIT;

这是一个更好的解决方案。它在第一个DOW中设置一个Hash对象,将所有术语,课程信息存储在同一个ID中,然后在第二个DOW中检查您的状况是否符合。如果所有ID保持在一起(群集),则不需要排序。有关详细信息,请参阅SAS哈希文档。

data have;
    input (id term course1 course2) (:$8.);
    cards;
21    201010  MAT        41                  
21    201010  MAT        51                  
21    201020  SPC        13 
21    201030  MAT        51 
21    201030  SPC        13 
29    201120  pos        94                  
29    201130  pos        94                  
;
run;



   data want;
if _n_=1 then do;
    dcl hash h();
    h.definekey('term','course1','course2');
    h.definedone();
end;
    do until (last.id);
        set have;
        by id notsorted;
        rc=h.add();
    end;

    length nextterm $3;

    do until (last.id);
        set have;
        by id notsorted;

        if h.check(key:cats(substr(term,1,4),input(substr(term,5),2.)+10),key:course1, key:course2) = 0 or 
            h.check(key:cats(input(substr(term,1,4),4.)+1,input(substr(term,5),2.)-20),key:course1, key:course2) =0 then
            nextterm='Yes';
        else nextterm = 'No';
        output;
    end;
    h.clear();
run;

答案 1 :(得分:0)

这是您可以使用的另一种方法 - 将数据集按相反顺序排序,检查每个课程是否在术语之间进行转换,然后将其重新排序为原始顺序:

data have;
    input id term (course1 course2) (:$8.);
    cards;
21    201010  MAT        41                  
21    201010  MAT        51                  
21    201020  MAT        51                  
21    201020  SPC        13                  
29    201120  pos        94                  
29    201130  pos        94                  
;
run;

proc sort data = have;
    by id course1 course2 descending term;
run;

data want;
    set have;
    by id course1 course2;
    length nextterm $3;
    nextterm = ifc(first.id or first.course2, 'No','Yes');
run;

proc sort data = want;
    by id term course1 course2;
run;