獨斷論

SAS 문법 - 8: DATA step의 디버깅(debugging) 본문

과학과 기술/SAS

SAS 문법 - 8: DATA step의 디버깅(debugging)

부르칸 2021. 9. 4. 15:39

Data step을 실행하였는데 원하는대로 변수값이 들어가지 않았을 때에는 SAS 코드를 한줄씩 실행해 가면서 어느 변수에 코딩이 잘못되어서 원하는 값이 들어가지 않았는지 확인하는 방법이 필요하다. 

DATA hospitaldat;
  input subj 1-4 name $ 6-23 no_vis 25 expense 27-34;
  totalexp = no_vis * expense;
  DATALINES;
1024 Alice Smith        7  1001.98
1167 Maryann White      2  29O9.34
1168 Thomas Jones       10 3904.89
1201 Benedictine Arnold 1  1450.23
1302 Felicia Ho         7  1209.94
1471 John Smith         6  1763.09
1980 Jane Smiley        5  3567.00
;
RUN;
 
PROC PRINT data = hospitaldat;
RUN;

위 코드를 실행하고 나면 아래와 같이 결과가 출력될 것이다. 

원래 데이터와 비교해보면  subj 1167의 expense값이 결측값이 되어버렸고 결과적으로 totalexp도 결측값이 되었다. subj 1168은 결측값은 아니지만 no_vis의 값이 잘못들어가있다. 이때 디버깅 기능을 사용하여 어디서부터 잘못되었는지 파악하면 코딩의 버그를 잡기가 쉬워진다(위와 같이 간단한 버그는 굳이 디버깅 기능을 사용하지 않더라도 input 문장과 datelines문장을 눈여겨보면 버그를 잡을수가 있지만, 코딩이 복잡해질수록 디버깅 기능을 사용하면 손쉽게 버그를 잡을수가 있으므로 알아두는 것이 좋다). 

 

디버깅 기능을 사용하기 위하여 data문장에 옵션을 추가한다. 

DATA hospitaldat /debug;
  input subj 1-4 name $ 6-23 no_vis 25 expense 27-34;
  totalexp = no_vis * expense;
  DATALINES;
1024 Alice Smith        7  1001.98
1167 Maryann White      2  29O9.34
1168 Thomas Jones       10 3904.89
1201 Benedictine Arnold 1  1450.23
1302 Felicia Ho         7  1209.94
1471 John Smith         6  1763.09
1980 Jane Smiley        5  3567.00
;
RUN;
 
PROC PRINT data = hospitaldat;
RUN;

/debug를 data hospitaldat에 추가하였다. 

그리고나서 F3를 누르거나 submit를 클릭하여 위 코드를 실행하면 아래와 같이 debugger log와 debugger source창이 뜬다. 

debugger log창의 > 다음에 커서가 보일텐데 여기에  examine _all_ 이라고 입력하자.

그러면 현재 변수의 값들이 뜨는데 앞서 이야기한것처럼 _N_은 1이 입력되어 있고 _Error_는 0이 입력되어 있으며 아직 input 문장을 수행하지 않았으므로 나머지 변수는 아무런 값도 존재하지 않는다.

이제 debugger log 창의 > 뒤에 마우스로 한번 클릭하고 엔터키를 치면 input 문장을 한번 실행하게 된다. 

debugger source창의 검은행 표시가 totalexp  문장으로 넘어가는데 이는 input 문장을 실행하고 totalexp를 실행하려고 대기중이라는 의미이다. 이제 debugger log 창의 > 바로 뒤를 마우스로 클릭하고 examine _all_을 다시 입력하고 엔터를 친다. 

_Error_는 0이고 subj, name, no_vis, expense는 값이 제대로 들어갔지만 totalexp값이 여전히 결측값이다. 이는 아직 totalexp를 계산하는 문장을 실행하지 않았기때문이다. 이제다시 debugger log의 > 뒤에 커서를 넣고 엔터를 치고 examine _all_을 입력한다. 

totalexp를 계산하는 문장을 실행하였으므로 totalexp=7013.86이라고 알려주었다. 다시 debugger log의 > 에 엔터를 치면 검은 줄이 input 문장으로 옮겨가는데 이는 이 문장을 다시 실행하려고 대기중이라는 의미이다. 여기서 debugger log의 > 뒤에 examine _all_을 입력하면 _N_의 값이 2가 되었을 것이다. 

debugger log의 >에서 엔터를 쳐서 input 문장을 실행하고 examine _all_을 입력하여 datalines의 2번째 행이 제대로 들어갔는지 검사해본다. 

코딩에 버그가 없다면 expense에 2909.34가 들어가야 하지만 결측값이 되었다. 데이터 1행의 expense는 제대로 값이 입력되었지만 2행은 값을 제대로 못 불러왔다는 것은 2909.34의 데이터값에 문제가 있다는 걸 의미한다. datalines를 잘보면 0(숫자 영)이 아니라 O(알파벳 O)가 있음을 알수 있다. 이제 알파벳 O를 숫자 0으로 바꾸고 /debug를 지우고 다시 SAS코드를 실행하여 데이터가 제대로 들어갔는지 검사해본다. 이를 위해 디버깅 작업을 중단해야 하는데 debugger log창을 클릭하고 SAS 전체창 메뉴에서 Run을 클릭하고 Quit debugger를 클릭한다. 

아래결과는 알파벳O를 숫자0으로 바꾸고 실행한 결과이다. 

subj 1167의 expense가 제대로 입력되었고 totalexp도 제대로 계산되었다. 하지만 subj 1168의 no_vis가 10이 아니라 1로 입력되었다. 다시 data hospitaldat에 /debug를 추가하고 debugging을 시작한다. 아래는 debugger log창에서 엔터를 7번 입력하여 subj 1168의 변수들을 읽은후 examine _all_을 실행한 결과이다. 

no_vis값이 10이 아니라 1이 들어갔으므로 no_vis의 input 문장이나 datalines의 no_vis에 해당하는 값을 유심히 살펴보면 no_vis의 열은 25가 아니라 25-26이어야함을 알수 있으므로 input 문장의 no_vis 25를 no_vis 25-26으로 고치고 /debug를 제거하고 SAS 코드를 실행한다. 

DATA hospitaldat;
  input subj 1-4 name $ 6-23 no_vis 25-26 expense 28-34;
  totalexp = no_vis * expense;
  DATALINES;
1024 Alice Smith        7  1001.98
1167 Maryann White      2  2909.34
1168 Thomas Jones       10 3904.89
1201 Benedictine Arnold 1  1450.23
1302 Felicia Ho         7  1209.94
1471 John Smith         6  1763.09
1980 Jane Smiley        5  3567.00
;
RUN;
 
PROC PRINT data = hospitaldat;
RUN;

Comments