도매시장 경락 데이터의 이해 - 당근
이번 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값에 있지 않을까하는 생각을 하게 되었다.
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)