도매시장 경락 데이터의 이해 - 당근

이번 Post에서 사용하는 데이터는 농림축산식품교육문화정보원에서 수집하여 공공데이터포털을 통해 제공되는 농수축산물 도매시장 상세 경락가격 Open API에서 수집한 데이터로 AWS S3 Agdata Lab 저장소에서 다운로드할 수 있다. 수집 기간은 2015년 1월부터 2018년 7월까지이며(정확히는 2018년 8월 1일) 전국 34개의 농산물 공영도매시장에서 거래된 당근 품목의 모든 데이터가 기록되어 있다.

먼저 csv파일을 읽어와서 dat 데이터로 저장하고 측정치 개수를 확인해보자. 그 결과 558,225개로, 총 43개월 중(2015년 1월 ~ 2018년 7월) 월 20일 도매시장이 개장되었다고 가정했을 때 하루 평균 거래 건수는 649.1건으로 단순화해서 볼 수 있겠으나, 날짜별 거래건수를 합해서 내림차순으로 정렬해서 상위 거래 건수를 확인해보면 거래가 많을 때는 1,000건 이상 있었던 것을 확인할 수 있다.

dat <- read.csv('carrot_2015-2018.csv')
print(paste('number of observation :',nrow(dat)))
## [1] "number of observation : 558225"
dat %>% group_by(date) %>% tally() %>% arrange(desc(n)) %>% head()
## # A tibble: 6 x 2
##       date     n
##      <int> <int>
## 1 20170512  1454
## 2 20170417  1273
## 3 20170120  1102
## 4 20170414  1090
## 5 20180213  1085
## 6 20170428  1061

앞선 포스트와 같이 필요한 변수들을 설정해준 후, histogram을 이용한 분포를 보면, 최대 kg당 약 10만원에 거래된 당근이 있는 것을 확인할 수 있다. 다시 kg당 5,000원 미만으로 필터링하여 histogram을 그려보면 실제 거래가 가장 많이 일어나고 있는 가격 범위는 1,500원 이하인 것을 확인할 수 있다.

gh1 <- ggplot(dat, aes(x = price_per_kg)) + geom_histogram(fill = "red", color = "red", bins = 1000)  
gh2 <- ggplot(dat %>% filter(price_per_kg<=5000), aes(x = price_per_kg)) + geom_histogram(fill = "firebrick2", color = "firebrick2", bins = 1000) 
grid.arrange(gh1, gh2, ncol=1, nrow=2)

아래 표와 같이 price_per_kg을 내림차순으로 정렬하여 상위 30개를 추려보면, 산지가 서울특별시 송파구인 곳이 많은 것을 알 수 있다. prut의 경우 1 이하인 것이 많은 것 또한 확인할 수 있다. 데이터를 들여다보면, 너무 낮거나 높은 price_per_kg값을 가지는 데이터들은 prut값이 일반적이지 않은 것을 볼 수 있다. price_per_kg이 너무 낮은 것들은 대부분 기존의 prut값을 10 또는 100으로 나눠주면 평균 당근 도매가와 비슷한 가격이 나온다. 반대로, price_per_kg이 너무 높은 것들은 prut값에 10 또는 100을 곱해주면 평균 당근 도매가와 비슷한 가격이 나오는 것을 확인할 수 있다. 그래서 이상치의 원인은 잘못된 prut값에 있지 않을까하는 생각을 하게 되었다.

Table 1: kg당 가격 기준 내림차순 데이터 상위 30개
aucCodeName bidTime date grade insname market package price prodname prut qty sanji sanji_wide sanji_city shipment spename unit year month day week wday weight sales_amt price_per_kg sanji_wide2
정가수의 a 20160324 충북원협(충주) 충주도매시장 봉지 107400 당근 1.00 1 서울특별시 송파구 서울특별시 송파구 3 세척당근 kg 2016 3 24 13 목요일 1.00 107400 107400.00 서울특별시
정가수의 a 20161028 익산원협(공) 익산도매시장 상자 945 당근 0.01 5 서울특별시 송파구 서울특별시 송파구 3 기타 kg 2016 10 28 44 금요일 0.05 4725 94500.00 서울특별시
정가수의 a 20160606 전주원협(공) 전주도매시장 상자 22164 당근 0.25 1 서울특별시 송파구 서울특별시 송파구 3 기타 kg 2016 6 6 24 월요일 0.25 22164 88656.00 서울특별시
정가수의 a 20160618 전주원협(공) 전주도매시장 상자 22148 당근 0.25 1 서울특별시 송파구 서울특별시 송파구 3 기타 kg 2016 6 18 25 토요일 0.25 22148 88592.00 서울특별시
정가수의 a 20170801 인터넷청과 구리도매시장 상자 720000 당근 10.00 10 a a NA 3 당근(수입) kg 2017 8 1 32 화요일 100.00 7200000 72000.00 a
정가수의 a 20170803 인터넷청과 구리도매시장 상자 720000 당근 10.00 -10 a a NA 3 당근(수입) kg 2017 8 3 32 목요일 -100.00 -7200000 72000.00 a
정가수의 a 20180315 동부청과 부산반여도매시장 상자 13000 당근 0.20 2 경기도 경기도 NA 3 당근(수입) kg 2018 3 15 12 목요일 0.40 26000 65000.00 경기도
정가수의 a 20160127 원주원협(공) 원주도매시장 상자 15750 당근 0.30 1 서울특별시 송파구 서울특별시 송파구 3 기타 kg 2016 1 27 5 수요일 0.30 15750 52500.00 서울특별시
정가수의 a 20161119 천안농협(공) 천안도매시장 상자 50000 당근 1.00 2 서울특별시 서울특별시 NA 3 흙당근 kg 2016 11 19 47 토요일 2.00 100000 50000.00 서울특별시
경매 a 20170921 무등급 이리청과 익산도매시장 상자 1347368 당근 30.00 1 전라북도 익산시 전라북도 익산시 3 당근(일반) kg 2017 9 21 39 목요일 30.00 1347368 44912.27 전라북도
정가수의 a 20150910 전주원협(공) 전주도매시장 상자 31500 당근 0.75 1 서울특별시 송파구 서울특별시 송파구 3 기타 kg 2015 9 10 37 목요일 0.75 31500 42000.00 서울특별시
경매 a 20170228 무등급 이리청과 익산도매시장 상자 1229166 당근 30.00 1 전라북도 익산시 전라북도 익산시 3 기타 kg 2017 2 28 10 화요일 30.00 1229166 40972.20 전라북도
정가수의 a 20170907 무등급 안양원협(공) 안양도매시장 상자 20000 당근 0.50 1 경기도 안양시 경기도 안양시 3 기타 kg 2017 9 7 37 목요일 0.50 20000 40000.00 경기도
정가수의 a 20170117 무등급 정읍원협(공) 정읍도매시장 78950 당근 2.00 1 광주광역시 광주광역시 NA 3 흙당근 kg 2017 1 17 4 화요일 2.00 78950 39475.00 광주광역시
정가수의 a 20150521 원주원협(공) 원주도매시장 상자 15750 당근 0.40 1 서울특별시 송파구 서울특별시 송파구 3 세척당근 kg 2015 5 21 21 목요일 0.40 15750 39375.00 서울특별시
정가수의 a 20170104 전주원협(공) 전주도매시장 상자 37800 당근 1.00 1 서울특별시 송파구 서울특별시 송파구 3 기타 kg 2017 1 4 2 수요일 1.00 37800 37800.00 서울특별시
정가수의 a 20170201 전주원협(공) 전주도매시장 상자 37800 당근 1.00 1 서울특별시 송파구 서울특별시 송파구 3 기타 kg 2017 2 1 6 수요일 1.00 37800 37800.00 서울특별시
정가수의 a 20170718 무등급 충북원협(청주) 청주도매시장 상자 1793 당근 0.05 10 서울특별시 송파구 서울특별시 송파구 3 세척당근 kg 2017 7 18 30 화요일 0.50 17930 35860.00 서울특별시
자기계산 a 20170125 정일청과 정읍도매시장 상자 69000 당근 2.00 2 광주광역시 북구 광주광역시 북구 9 당근(일반) kg 2017 1 25 5 수요일 4.00 138000 34500.00 광주광역시
정가수의 a 20170826 농협창원(공) 창원팔용도매시장 기타 32000 당근 1.00 1 경상남도 창원시 경상남도 창원시 4 세척당근 kg 2017 8 26 35 토요일 1.00 32000 32000.00 경상남도
정가수의 a 20150718 강릉농산물 강릉도매시장 기타 32000 당근 1.00 10 서울특별시 서울특별시 NA 3 당근(일반) kg 2015 7 18 29 토요일 10.00 320000 32000.00 서울특별시
정가수의 a 20180102 충북원협(충주) 충주도매시장 12780 당근 0.40 1 서울특별시 송파구 서울특별시 송파구 3 기타 kg 2018 1 2 2 화요일 0.40 12780 31950.00 서울특별시
매수도매 2016-03-31 :: 20160331 동화청과 서울가락도매시장 3188 당근 0.10 1 a a NA a 당근(수입) kg 2016 3 31 14 목요일 0.10 3188 31880.00 a
정가수의 a 20170501 6등 충북원협(청주) 청주도매시장 상자 31650 당근 1.00 2 서울특별시 송파구 서울특별시 송파구 3 흙당근 kg 2017 5 1 19 월요일 2.00 63300 31650.00 서울특별시
정가수의 a 20170501 6등 충북원협(청주) 청주도매시장 상자 31650 당근 1.00 20 서울특별시 송파구 서울특별시 송파구 3 흙당근 kg 2017 5 1 19 월요일 20.00 633000 31650.00 서울특별시
정가수의 a 20161128 전주원협(공) 전주도매시장 상자 31649 당근 1.00 1 서울특별시 송파구 서울특별시 송파구 3 기타 kg 2016 11 28 49 월요일 1.00 31649 31649.00 서울특별시
정가수의 a 20150904 전주원협(공) 전주도매시장 상자 31609 당근 1.00 1 서울특별시 송파구 서울특별시 송파구 3 기타 kg 2015 9 4 36 금요일 1.00 31609 31609.00 서울특별시
정가수의 a 20160813 충북원협(청주) 청주도매시장 상자 8440 당근 0.30 1 서울특별시 송파구 서울특별시 송파구 3 세척당근 kg 2016 8 13 33 토요일 0.30 8440 28133.33 서울특별시
정가수의 a 20170301 무등급 정읍원협(공) 정읍도매시장 52640 당근 2.00 1 광주광역시 광주광역시 NA 3 흙당근 kg 2017 3 1 10 수요일 2.00 52640 26320.00 광주광역시
정가수의 a 20161006 전주원협(공) 전주도매시장 상자 25531 당근 1.00 1 서울특별시 송파구 서울특별시 송파구 3 기타 kg 2016 10 6 41 목요일 1.00 25531 25531.00 서울특별시

raw 데이터에서 산지가 송파구인 데이터만 필터링하여 단위가격이 낮은 순에서 높은 순으로 정렬하였다. 약 28,440번째 순위에서 급격하게 증가하는 것을 볼 수 있다. 또한 그 중 1kg 이하의 거래단량을 가진 거래들에서 높은 price_per_kg값들이 많은 것을 확인할 수 있었다.(*raw 데이터는 3개만 g으로 되어있고, 나머지는 모두 kg이었다.) 그래서 다시 1kg 이하의 거래들만 필터링한 결과, 너무 높다 싶은 price_per_kg을 가진 값들은 배제가 되고, 최대 18,900원에서 그치는 것을 볼 수 있었다.

d1 <- dat %>% filter(sanji_city == '송파구')
g1 <- ggplot(d1 %>% arrange(price_per_kg) %>% mutate(SEQ=seq(1,nrow(d1),1))) + geom_line(aes(x=SEQ,y=price_per_kg), linetype='solid', size=0.5, alpha=0.8, color='blue') 
d2 <- d1 %>% filter(prut>1)
g2 <- ggplot(d2 %>% arrange(price_per_kg) %>% mutate(SEQ=seq(1,nrow(d2),1))) + geom_line(aes(x=SEQ,y=price_per_kg), linetype='solid', size=0.5, alpha=0.8, color='blue') 
subplot(ggplotly(g1),ggplotly(g2), margin = 0.05, nrows=2)