불규칙한 값들인 경우를 고려한 Loop 작업 1.

사실, 오늘 말할 것은 제목 뽑기가 가장 어려운 일이네요....그러니까 오늘 무엇을 할 것이냐하면, 예를 들어 이런 데이터와 작업이 있다고 하죠.... 한국, 중국, 미국의 기업매출 자료가 각각 세개의 파일로 나뉘어 있다. 한국은 1990년 10개 기업, 91년 20개 기업, 92년 30개 기업 중국은 90년 20개 기업, 91년 14개 기업 미국은 90년 10개, 91년 8개, 92년 30개, 93년 50개 기업 이때, 각 국가 파일별로 각연도별 매출액 평균액을 계산한다고 하자.. 당연히 이러한 작업은 각 연도별로 평균액을 계산하는 것은 루프문으로 작성하는 것이 효율적이다. 그러나 문제는 국가별로 시작연도는 같은데, 마지막 연도가 다르다는 점...이걸 어떻게 자동(?)으로 연동할까? 먼저, 한국파일을 열어서 아래의 실행문을 돌리면, 연도의 기초통계가 나올 것이고....     su year 스타타는 이러한 기초통계결과를 임시로 저장한다. 무엇을 저장하는지는 return list 를 실행해 보길.... 여튼 위와 같은 경우 실행한다고 가정하면, r(max) = 1992   이라는 부분이 있다...바로 이걸 이용하면 각 국가별 파일마다 마지막연도를 특정값으로 지정하지 않고 쓸 수 있다....     su year     forvalues yy = 1990(1)`r(max)' {        su  매출액변수 if year == `yy'     } 완전 자동화하려면, 3개의 파일을 append로 합치고  각 국가별 작업도 루프로 작성하면 됨. foreach cc in 한국 중국 미국 {     su year if countryname == "`cc'"     forvalues yy = 1990(1)`r(max)' {   ...

라벨 다루기: 라벨내 문자열 바꾸기: macro 활용

// 스타타를 사용하다보면, 새로운 변수들을 생성한다. // 또한 변수명은 축약해서 쓰지만, 변수가 의미하는 바를 구분하기 위해 라벨을 사용한다. // 오늘 해 볼 것은 기존 유사한 변수들에 대한 유사한 작업을 반복해서 하는 경우가 있다. // 이때, 새로운 변수들을 구분하기 위해 라벨을 붙이게 되는데, 기존 변수들의 라벨과 일부 문자만 다르고 내용은 동일한 경우 일일이 라벨문을 작성하는 것은 짜증나는 일이다. 왜냐면 단순작업이니까..... // 먼저, 다음과 같은 변수들이 이미 있다.      lab var rgn_base "납세지역(기초)"           lab var taxrev "세수(기초)"     lab var prn_all "납세인원(전체,기초)"     lab var prn_part "납세인원(세액>0,기초)"            gen rgn_larg = int(rgn_base/100)       // rgn_base는 총 네자리 숫자인데, 이중 앞의 두자리는 광역을 의미하는 코드이고, 뒤의 2자리는 기초지역을 의미하는 코드이다. 그래서 앞의 두자리를 떼내어  rgn_larg이라는 광역지역을 의미하는 변수를 새로 만들었다...      lab var rgn_larg "납세지역(광역)"         sort  rgn_larg    // 광역코드를 기준으로 정렬하고... // 기초단위의 세수,납세인원1,2변수의 합계값들에 대한 새로운 변수를 생성하고, 기초지역 관련 변수의 라벨에 있는 "기초"라는 문자를 "광역"으로 바꾸려고 한다....     foreach myvar of varlist taxrev...

그래프 그리기 07:= OECD 국가들의 개인소득세 최고세율의 변화: 1981~2010:= 막대그래프

이미지
아래의 그래프는 OECD 국가들의 개인소득세의 최고세율 변화(1981,1990,2000, 2010)를 보여주고 있는데요.... 와!! 대단하죠...예전에는 최고세율이 상당히 높았군요...근데 지금은 많이 떨어졌네요... 이것이 양극화의 원인일까요? 적어도 부분적으로는 그래 보입니다.... 여하튼 이것은 엑셀에서 작성한 것입니다.... 엑셀도 좋은 프로그램이죠..ㅋ 좀 더 구체적으로 말하면, 국가별로 4개 연도씩 묶어서 막대그래프를 그려야 하고, 평균치를 의미하는 선과, 화살표, 설명이 있습니다. Source: OECD(2012), "Trends in personal income tax and employee social security contribution schedules" // 동일한 데이터에 대해 스타타를 이용해서 작성한 것입니다. // 먼저,  국가별로 4개 연도씩 묶어서 막대그래프는 graph bar [ 각연도별 변수 ], over( groupbar ) 를 이용해 그립니다. #delimit ;   graph bar incometax1981  incometax1990 incometax2000 incometax2010  ,    over(country,gap(*2.5) label(angle(ninety) labsize(vsmall)) sort(incometax1981) descending)     ylabel(0(10)100, grid angle(horizontal) labsize(vsmall))      legend(order(1 "1981" 2 "1990" 3 "2000" 4 "2010") row(1) size(small) position(12) ring(0) region(lcolor(none)) fcolor(none) )   scheme(economist) ...

그래프 그리기 06:= 등탄력적 효용함수 그래프 그리기

이미지
// 스타타를 이용하여 일반 함수, 즉 y=x ,  y=x^2 + x + 3 와 같은 함수를 그리고 싶을때 // 오늘은 경제학에서 자주 사용되는 등탄력적 효용함수를 그려보도록 하겠습니다. 이때, 탄력도의 차이에 따른 함수 형태의 차이를 보고자 합니다. // 그리고 탄력도의 차이에 따른 함수에 따라 소득수준에 따른 한계효용의 변화 역시 비교합니다. // 등탄력적 효용함수의 일반적 형태...         // 이러한 효용함수의 특징은 소득수준에 따라 탄력도가 항상  ε 로 같다는 것입니다. // 즉,  ε 값에 따라 그 함수를 그리면 됩니다. // 함수를 그리는 기본적인 코드는 다음과 같습니다. twoway (function y = (x^(1-0) - 1)/(1-0),     range(0 5)     // ε=0일때, x값 범위를 0과 5로하여 그래프를 그리시오....    // 즉,  ε=0일때, 위 함수는 y=x-1이 됩니다...    // 이건 스타타 명령어 줄에서 아무런 자료가 없어도 그려집니다... 위의 function이라는 부분땜시...ㅋ // 여하튼,  ε 가 0 , 0.5, 1, 2, 5일때 각 함수를 하나의 그래프로 그리려면.... #delimit ; twoway (function y = (x^(1-0) - 1)/(1-0),     ra(0 5) lcolor(black) lwidth(medium) lpattern(solid))        (function y = (x^(1-0.5) - 1)/(1-0.5), ra(0 5) lcolor(blue) lwidth(medium) lpattern(solid))        (function y = (x^(1-1...

그래프 그리기 05:= EU-15 국가들의 GDP 대비 사회지출 비중과 사회지출 대비 사회보장기여금의 비중:= 4사분면 만들기

이미지
// 이번에 간단하게 그래프에 4사분면을 구획하는 방법입니다. // 이를 위해 사용한 자료는 2010년 기준  "EU-15 국가들의 GDP 대비 사회지출 비중과 사회지출 대비 사회보장기여금의 비중"입니다. // 이것은 국가별로 사회지출에 필요한 재원조달에 있어서 사회보장기여금(=사회보험료)이 어느 정도 역할하는가에 대한 국가간 비교를 통해  복지모델 유형화를 하거나 혹은 유형을 확인하는 것입니다. // 1999년 Bonoli가 처음 시도했다고 해서, 일명 "Bonoli Matrix"라고도 합니다. // 자, 보면, 중간에 선이 들어가 있는데, 이 선은 15개 국가들만의 평균값입니다.. 즉, 각 평균값을 기준으로 선을 그으면 4사분면이 생기죠....^^ // 변수: ser  (사회지출비중),  sc_se (사회지출 대비 사회보장기여금의 비중) #delimit ;  twoway (scatter ser sc_se , mlabel(wid) mlabposition(3)) if yr == 2010   , xlabel(3 61 , grid )   ylabel(23 33  , angle(horizontal))  xline(41.6 ,  lwidth(thick) lpattern(solid) lcolor(gs13) )  yline(26.9 ,  lwidth(thick) lpattern(solid) lcolor(gs13) )    ; // 보시면, 이해하실거란 생각해서 별 다른 설명은 하지 않겠습니다. // 다만, 2010년이 아니라 여러 연도에 대해서 동일한 그래프를 반복해서 그리고 싶죠?!^^ // 그러러면, 횡축과 종축의 최대값과 최소값, 그리고 각각의 평균값들을  로컬변수로 받아내서 반복문을 만들면 되겠죠!!

그래프 그리기 04:= 특정 시기에 음영 넣기:= OECD 국가들의 총조세와 사회지출이 GDP에서 차지하는 비중(1980~2012)

이미지
// 간혹, 아니 어찌보면 자주 그래프에 특정 시기를 음영으로 넣고 싶을 때가 있죠!! // 예를 들어, 각 정권 기간 동안 거시변수가 어떤 추이를 비교하거나, 특정 사건 전후로 달라지는 추이를 비교하는 경우...  // 오늘의 사례는 "2007년 금융위기 이후 OECD 국가들의 총조세와 사회지출이 GDP에서 차지하는 비중(1980~2012)"으로서, 2007년 금융위기 이후 기간을 음영으로 표시하는 것입니다.  // 먼저, 자료에 대한 간단한 설명을 하자면, // 기간은 1980~2012년 // 변수: 1) ser (복지지출 비중),  2) tax (총조세 비중) , 3) yr  (연도) , 4) country (국가명 및 OECD 평균) // 보통 두 시계열 변수에 대한 선그래프는 다음과 같이 하면 되죠... twoway     /// (line ser yr if country == "OECD - Total",lpattern(solid))  /// (line tax yr if country == "OECD - Total",lpattern(dash)) // 자 이제 여기에 음영을 넣어볼까요.... twoway /// (function y=26.9, range(2007 2013) recast(area) color(gs13) base(15.5) ) // 이게 무슨 말인가 하면, y=26.9 라는 직선을 그려라... 이때, x축의 범위는 2007~2013이고, 그래프는 영역형태이며  recast(area) ,  색깔은 회색이고, 최소값은 15.5이다. // 당연히 그리려는 그래프마다 바꿔줘야 하는 것은  26.9와 15.5라는 숫자이고, 기간 연도 역시 바꾸면 되겠죠... // 그런데 문제는 이렇게 음영을 그리면 회색영역이 생뚱맞게 있다는 점...그래서 회색영역에 눈금을 알 수 있는 선(grid)을 그어줘야 품질좋은 ...

pdf 문자 인식(OCR)

acrobat을 이용하면 대부분 pdf문서의 문자들을 인식하여(OCR기능), 한글, 워드 및 엑셀에서 유용하게 사용할 수 있다. 그러나, 종종 렌더링(rendering)문제가 생겨 문자를 인식하지 못하는 경우가 있다. 이때, 해결방법은 두 가지가 같다. 첫째, 1) pdf문서 인쇄 시 프린터를  microsoft XPS document writer로 인쇄해서 xps문서 만들기 2) xps문서를 pdf로 전환 3) 전환된 pdf문서에서 OCR 기능 실행하면  ~~ 끝!! 둘째, 1) pdf문서를 다른 이름으로 저장할 때, 그 형식으로 tif 혹은 tiff로 저장 2) 페이지별로 생성된 그림파일들을 pdf문서로 결합 3)결합된 pdf문서에서 OCR 기능 실행하면 ~~끝!! (다른 그림 파일들은 안됨!! 사실, 해보지는 않았음 ~ㅋ)

그래프 그리기 03:= 여러 집단별로 동일한 그래프를 반복해서 그리기

이미지
/* 원본 데이터는 A열의 대분류(종사상지위,근로형태,산업 등)와 B열의 중분류가 각 해당 대분류별로 구성된 항목별로 2001년~2012년까지의 값이 들어있는 자료이다(제공:= 신우진). */ // 이런 자료를 갖고서 어떤 그래프를 그려야 할까?^.^ // 좀 더 구체적으로 말하면, A열의 분류(근로형태별, 산업별, 종사상지위별 등)로 각각의 그래프를 B의 중분류 항목을 기준으로 연도별 추이를 그려야 하는 것이 오늘의 작업... // 오늘의 작업을 정리하면,  1. A열의 항목별로 별도의 그래프를 그려야 한다. 다만, 그래프의 형식은 다행히도 동일하다.  2. 각 그래프는 B의 항목을 기준으로 그린다. 즉, 각 그래프의 범례(legend)는 B열의 항목으로 한다.  // 만일 이 작업을 하나하나씩 그린다면, 시간이 많이 걸리고 번거로운 것 당연!!  // 자! 시작해 볼까요^^ // 먼저, 스타타로 그래프를 그릴려면, 위의 원본을 다음과 같은 형태로 일단 변환하는 것이 필요합니다.    * 오늘의 작업은 그래프 그리기이니, 이러한 형태로 변환하는 것은 나중에 기회가 되면 설명할께요.  여기에 더 관심이 있는 분은 import excel과 reshape 명령어를 공부하면 될 겁니다.... * 자! 다시 한 번 이번 작업에서의 핵심을 말하면 다음과 같습니다.  1. A열의 항목과 B의 항목을 각각 하나의 목록으로 받아내서 사용할 수 있어야 한다. 2. A와 B의 각 항목명을 문자로 인식, 즉 항목명은 물론 각 항목명 시작과 끝부분에 인용부호를 그대로 인식하여 사용할 수 있어야 한다. 구체적으로 말하면, " 항목명 " 의 형태를 살리면서 목록을 만들수 있어야 한다(스타타에서는 이게 생각보다 힘들다..물론, 알면 쉽지만 모르면 ㅠ.ㅠ) levelsof A, loc(grpA)  // 대분류 항목 목록 만들고 fore...

서명

이미지

그래프 그리기 02:= 막대(bar) 그래프

이미지
* 스타타에서 막대그래프는 약간 불편하다. 두 변수를 서로 다른 막대로 그리기도 어렵고, 값을 그래프 안에 넣기도 어렵다... ㅠ.ㅠ // 오늘 그래프를 만들 데이터는 다음과 같다. // yr을 x축, 나머지 세변수를 y축... // 세 변수 중 B, C는 막대그래프 좌축 // D는 선연결그래프로 우축으로... // 이 경우, 대부분은 이렇게 그리겠죠.... #delimit ; twoway (bar var_B yr) (bar var_C yr) (connected var_D yr, yaxis(2) mlabel(var_D)  mlabposition(12))   ,    ytitle("근로자수(천명)")    ytitle("비정규직 비중(%)", axis(2))    ylabel(0(2000)20000, angle(horizontal))     ylabel(0(5)40, axis(2) angle(horizontal) )    xtitle("")    xlabel(2001(1)2012 , labsize(medium) alternate )    legend(order(1 "`mylab_B'" 2 "`mylab_C'"  3 "`mylab_D'" ) rows(1))     scheme(sj)  ; * 그래서 다음과 같이 해보죠... format var_D %16.1f                // 비율을 소수점 1자리수로... format var_B var_C %16.0fc     // 1000단위로 콤마를 넣고.. // 핵심... gen yr2 = yr + 0.2 gen yr3 = yr - 0.2 #delimit ; twoway...

그래프 그리기 01

이미지
  * 이런 그래프를 그리는 방법.. #delimit ; ** 1.1. 소득계층/급여종별 가입개월수 ; twoway   (line myval sim_yy if vartype == 6 &  qtype == 1, sort lwidth(thick) lcolor(gs10)   lpattern(dash))          (line myval sim_yy if vartype == 6 &  qtype == 2, sort lwidth(thick) lcolor(gs14)  lpattern(solid))          (line myval sim_yy if vartype == 6 &  qtype == 3, sort lwidth(thick) lcolor(gs10)  lpattern(solid))          (line myval sim_yy if vartype == 6 &  qtype == 4, sort lwidth(thick) lcolor(gs5)   lpattern(solid))          (line myval sim_yy if vartype == 6 &  qtype == 5, sort lwidth(thick) lcolor(black) lpattern(solid))          if bentype != 99            , by(bentype,rows(1))  by(, note(""))    ytitle(가입개월수)    ylabel(120(60)360, angl...

일정 범위 혹은 특정 값들의 목록을 조건 걸기

// 일정 범위 혹은 특정 값들의 목록을 조건 걸기 * inrange 와 inlist // 많은 사람들이 이렇게 쓰지요?! 명령구문   if var_a >= 1 & var_a <= 10 // 그런데 이렇게 하면 편하죠^^ 명령구문   if inrange(var_a,1,10) // 아니면, 이렇게 할 수도 있습니다. 물론, 지금은 inlist가 별로 소용없어 보이지만, 일정 범위가 아니라면, inlist처럼 목록을 조건걸 때는 너무 편하겠죠^^; 명령구문   if inlist(var_a,1,2,3,4,5,6,7,8,9,10)

특정 변수의 값들을 다른 변수의 값 라벨로 사용

이미지
* 변수B에 있는 연령대를 의미하는 문자값들을 u5_age 변수에 있는 1~10까지의 값에 대한 값라벨로 사용하고자 하는 경우         lab def lbl_age 0 ""   // 일단 하나 값라벨을 정의하고...    forvalues ii = 1(1)10  {     loc mystr = B[`ii']      // 각 행에 있는 값을 로컬로 담아두고       lab def lbl_age `ii' "`mystr'" , add   // 숫자와 함께 값라벨을 계속 추가하자..   }     lab val u5_age lbl_age   // 정의한 라벨을 적용하자.

불균형 패널을 균형패널로 만들기

이미지
* 다음과 같은 자료가 있습니다. // 1~5까지의 값을 갖는 old_Act의 경우 일부 집단에서 특정 값이 빠진 경우.  fillin gend agez old_Act   // 빠진 것을 채우고 // 문제는 새롭게 생성한 관측치에 특정 값을 넣어야 함 // old_Act 값에 따라, 그 값이 포함된 변수에만 1을 넣고 다른 경우에는 0을 넣어봅니다.     replace _fillin = old_Act if _fillin == 1     forvalues ii = 1(1)5 {         replace trate`ii' = (_fillin == `ii') if trate`ii' == .      } // 이렇게 한 줄을 줄여도 되겠죠...^^~     forvalues ii = 1(1)5 {         replace trate`ii' = (old_Act == `ii') if trate`ii' == .      }

변수 첫행에 있는 값을 변수명으로 전환

  ** 첫행의 값 받아서 목록으로 만들기     loc mystrz ""   foreach myvar of varlist D-AE {     loc mystr = `myvar'[1]                // 첫행의 값 받기     loc mystrz: list mystrz | mystr     // 받은 값들을 목록으로 만들기   }   ** 목록 내 한글을 영문으로 바꾸기: 한글은 변수명으로 사용할 수 없자나~~ ㅠ.ㅠ   local mystrz: subinstr local mystrz "사업장" "wp", all   local mystrz: subinstr local mystrz "지역" "lp", all   local mystrz: subinstr local mystrz "임의계속" "vcp", all   local mystrz: subinstr local mystrz "임의" "vp", all   ** 목록을 변수이름으로 전환하기     loc ii 0   foreach myvar of varlist D-AE {     loc ++ii     loc mystr: word `ii' of `mystrz'     gen `mystr' = real(`myvar')   }   drop D-AE

변수 안에 있는 값들을 목록으로 받아내기

foreach mysex in 1 2  {  // 성별 루프    forvalues myeact = 11(1)15   {  // 종사상지위별 루프         // 성과 종사상지위에 따른 집단 내 구성원들의 연령구성은 다양할 것임.       // 그래서 각 집단 내 구성원들의 연령 목록이 필요함^^       levelsof realage if gend == `mysex' & eactpp == `myeact' , local(myages)       foreach myage of local myages  { // 연령          svy: mean pen_part if gend == `mysex' & eactpp == `myeact' & realage == `myage'               }  // 연령    }  // 종사상지위 }  // 성별

균등(uniform) 확률 뿌리기

// 0~1 사이의 난수를 생성해서 특정 값 뿌리기 // 일단 스타타 본래의 기능으로 불가능함. // 그래서...... ^.^        qui  gen rand = runiform() if gend == 1 & age == 18  // 성연령별로 0~1 사이의 난수생성        qui  replace nps_pmon_yr =          ///                         cond(rand <= 0.12, 1 ,   ///                         cond(rand <= 0.21, 2 ,   ///                         cond(rand <= 0.34, 3 ,   ///                         cond(rand <= 0.44, 4 ,   ///                         cond(rand <= 0.49, 5 ,   ///                         cond(rand <=...

변수라벨 복사하기

  lab var tpop "총인구수"   lab var pr1 "비율: 임금[상용]"   lab var pr2 "비율: 임금[임시]"   lab var pr3 "비율: 임금[일용]"   lab var pr4 "비율: 비임금[고용주]"   lab var pr5 "비율: 비임금[자영자]"   lab var pr6 "비율: 비임금[무급가족]"   lab var pr7 "비율: 실업자"   lab var pr8 "비율: 비경활[일반]"   lab var pr9 "비율: 비경활[구직단념]"       loc mlab  "비율: " /* 위의 변수들의 라벨에서  "비율: "이라는 문자를 아래의 "인구수"라는 문자로 바꾸기 위한 설정. 이때, 위에서 해당 문자와 다른 문자사이의 스페이스를 띄워야함 */   forvalues myval = 1(1)9  {     gen np`myval' = round(tpop*pr`myval')     loc mylab: var label pr`myval'  // 기존 라벨을 local로 설정     loc mylab: list mylab - mlab    // 매크로 리스트를 통해, 특정 문자열 제거     lab var np`myval' "인구수:`mylab'"   }

대용량 자료 처리 팁 (2)

* ########################################### * 9. 퇴직시점별 Peak Value == 퇴직연기시 납부할 추가 보험료 고려.. * ########################################### * 사업주 부담분 포함     gen pval = .       lab var pval "정점가치"       su yage       loc Amin = r(min)       loc Amax = r(max) * 법정수급연령[구 60세]는 불필요...이후 시점이 없기때문임.         forvalues myval = `Amin'(1)`Amax'  {    // 퇴직연기시 최대기대자산값 구하기.       by sn: gen TempMax = epw if yage == `myval'       by sn: replace TempMax = max(TempMax[_n-1], epw) if yage >= `myval'       by sn: replace TempMax = TempMax[_N] if yage >= `myval'       by sn: gen MaxAge = yage if epw == TempMax      // 최대기대자산의 획득 연령       by sn: replace MaxAge = sum(MaxAge) if yage >= `myval'       by sn: replace MaxAge = MaxAge[_N] if yage >= `myval'   ...

대용량 자료 처리 팁(1)

* 10.3. 퇴직연기시 최대 기대효용과 현재 퇴직시 기대효용의 차이    loc mygamma = int(`Gamma'*100)   // 정수화: 감마는 1보다 작고 소수점 두 자리..   loc mykappa = int(`Kappa'*100)   // 정수화: 카파는 1보다 크고 소수점 두 자리    gen opv_g`mygamma'_k`mykappa' = .    lab var opv_g`mygamma'_k`mykappa' "Option Value[G=`Gamma',K=`Kappa']"    su yr    loc YrMin = r(min)    loc YrMax = r(max) forvalues myval = `YrMin'(1)`YrMax'  {         by sn: gen TempMax = Vh_y`myval' if yr == `myval'       by sn: replace TempMax = max(TempMax[_n-1], Vh_y`myval') if yr >= `myval'       by sn: replace TempMax = TempMax[_N] if yr >= `myval' ** 퇴직연기를 통해 얻을 수 있는 최대기대자산의 효용        by sn: gen Vh_max_y`myval' = TempMax - Vh_y`myval' if  yr == `myval'  //  ** Option Value  // 퇴직연기에 따른 최대기대자산에서 현재 퇴직하는 경우의 기대자산의 차이    by sn: replace opv_g`mygam...