我如何创建一个变量取决于其他观察
how can i create a variable depends on other observations
我有一个大学数据,问题是查找相同的 ID、相同的课程 1 和课程 2 是否有下学期。我有 table 如下前 4 个变量:id、term、course1 和 course2。我正在尝试创建第 5 个变量 'nextterm'。条款是这样的:201010-201020-201030-201110-201120-201130-201210,...等等。所以 id=21,课程 1 和课程 2 是 201010 和 201020 的相同 MAT 51。所以 201010 将是,201020 将是否。
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
好的,这是更新的答案,它需要一定程度的SQL了解,如果您的数据量不是太大,它可以工作。请注意,我已将传入数据集中的术语转换为数字,但也可以即时完成。如果你觉得它运行太慢,那么我建议 1. 在 id 中按降序对你的数据进行排序, 2. DOW 或 Hash 应该足够了。
data have;
input id term (course1 course2 ) (:.);
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 Hash文档
data have;
input (id term course1 course2) (:.);
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 ;
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;
您可以使用另一种方法 - 将数据集倒序排序,检查每门课程是否在学期之间延续,然后将其排序回原始顺序:
data have;
input id term (course1 course2) (:.);
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 ;
nextterm = ifc(first.id or first.course2, 'No','Yes');
run;
proc sort data = want;
by id term course1 course2;
run;
我有一个大学数据,问题是查找相同的 ID、相同的课程 1 和课程 2 是否有下学期。我有 table 如下前 4 个变量:id、term、course1 和 course2。我正在尝试创建第 5 个变量 'nextterm'。条款是这样的:201010-201020-201030-201110-201120-201130-201210,...等等。所以 id=21,课程 1 和课程 2 是 201010 和 201020 的相同 MAT 51。所以 201010 将是,201020 将是否。
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
好的,这是更新的答案,它需要一定程度的SQL了解,如果您的数据量不是太大,它可以工作。请注意,我已将传入数据集中的术语转换为数字,但也可以即时完成。如果你觉得它运行太慢,那么我建议 1. 在 id 中按降序对你的数据进行排序, 2. DOW 或 Hash 应该足够了。
data have;
input id term (course1 course2 ) (:.);
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 Hash文档
data have;
input (id term course1 course2) (:.);
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 ;
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;
您可以使用另一种方法 - 将数据集倒序排序,检查每门课程是否在学期之间延续,然后将其排序回原始顺序:
data have;
input id term (course1 course2) (:.);
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 ;
nextterm = ifc(first.id or first.course2, 'No','Yes');
run;
proc sort data = want;
by id term course1 course2;
run;