2015-06-18 2 views
0

У меня есть данные колледжа, проблема заключается в том, что если один и тот же идентификатор, тот же курс1 и курс2 имеют следующий термин или нет. У меня есть таблица, как ниже, первые 4 переменные: id, term, course1 и course2. Я пытаюсь создать 5-ю переменную 'nextterm'. Условия таковы: 201010-201020-201030-201110-201120-201130-201210, ... так далее. Так ID = 21, course1 и конечно 2 такие же MAT 51 для 201010 И 201020. Так 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 

ответ

0

Ok, это обновленный ответ, он требует некоторое понимание 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; 

Это лучшее решение. Он устанавливает объект Hash в первом DOW для хранения всего термина, информации о курсе в пределах одного идентификатора, а затем во втором DOW, чтобы проверить, соответствует ли ваше состояние. Это не требует сортировки, если все идентификаторы остаются вместе (сгруппированы). Подробнее см. В документах SAS Hash.

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; 
+0

Это в основном верно , Но, возможно, я не упомянул прав. Термин «линия» похож на 201120-201130-201210. Когда данные переходят с 201130 по 2012 год10, это не показывает это? Как я могу это показать? Спасибо за ответ. Я не знал его опережающую технику, не смог найти имя для вызова. – joys

+0

Мои извинения. Я не читал это правильно, но затем он приносит с моей стороны больше вопросов: 1. Как построены ваши термины? это всегда 4 цифры года плюс число увеличилось на 10? таких как 201120-201130, и сколько терминов у вас есть каждый год? 2. Как выглядят ваши данные. У вас есть время от времени 201110, переходя к 201130 году, то есть студент пропускает весь термин? И если это произойдет, вы считаете, что 201130 станет следующим термином 201110? Ответы на эти вопросы имеют решающее значение для определения подходов к программированию. –

+0

Каждый год имеет 3 условия. год + 10 или 20 или 30. Итак, следующим образом, 201010- 201020-201030-201110-201120-201130-201210-201220 -, .... так далее. Все условия таковы. Нет прыжков, 201110, то 201120 – joys

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; 
+0

это гладкий подход, однако он не будет работать на тех же курсах, которые пропускают термины. 21 201010 MAT 51 21 201020 SPC 13 21 201030 MAT 51 –

+0

Для более надежного подхода я бы предложил настроить массив или объект Hash, где вы можете временно сохранить информацию о курсе, а затем посмотреть вверх, чтобы подтвердить. –

+0

Извините, что они никогда не ожидали увидеть пропуски в одном из своих комментариев на ваш ответ, так что это не должно быть проблемой. – user667489

Смежные вопросы