다섯 수치 요약은 연속형 자료로 이루어진 데이터를 5개의 기술통계량으로 설명하는 방법이다. 이는 보통 최소값, 제1사분위수, 중앙값, 제3사분위수, 최대값으로 이루어진다. 이것은 매우 간단하면서도 유용한 자료 요약 기법이다. 중앙값을 통해 자료의 중심을 확인할 수 있고, 최대최소값을 통해 자료의 범위를 파악할 수 있다. 또한 사분위수들을 중앙값과 최대최소값과 비교하여 살펴봄으로써 대략적인 자료의 산포를 확인할 수 있다. R에서는 summary()와 fivenum()의 두 가지 방법을 통해 다섯 수치 요약을 수행할 수 있다.
summary()와 fivenum()의 차이를 알아보기 위해 다음의 예시를 살펴보자.x는 1부터 9까지의 홀수로 이루어진 벡터이며 자료의 크기는 5이다. x에 대해 각각 summary()와 fivenum()을 실행한 결과는 다음과 같다.
x = seq(1, 9, by=2)
x
## [1] 1 3 5 7 9
fivenum(x)
## [1] 1 3 5 7 9
summary(x)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 1 3 5 5 7 9
가장 눈에 띄는 차이점은 fivenum()은 최소값, 제1사분위수, 중앙값, 제3사분위수, 최대값의 총 5개의 값을 반환하고, summary()는 여기에 평균까지 더하여 총 6개의 값을 반환한다는 점이다. 이외에는 두 함수가 반환하는 결과값은 모두 동일하다.
이번에는 조금 다른 예시를 살펴보자. y는 1부터 11까지의 홀수로 이루어진 벡터이며 자료의 크기는 6이다. y에 대해 각각 summary()와 fivenum()을 실행한 결과는 다음과 같다.
y = seq(1, 11, by=2)
y
## [1] 1 3 5 7 9 11
fivenum(y)
## [1] 1 3 6 9 11
summary(y)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 1.0 3.5 6.0 6.0 8.5 11.0
두 함수가 반환한 제1분위수와 제3분위수의 값이 약간 다르다는 것을 확인할 수 있다. x에 대해서는 두 함수의 결과가 동일했지만 y에 대해서는 다른 결과가 나왔다. 이를 설명하기 위해서는 사분위수를 계산하는 각각의 방법을 살펴보아야 한다.
fivenum()
summary()
각각의 방법으로 y에 대한 제1사분위수를 구해보자. 먼저 fivenum() 방법에서는 중앙값을 구해야 한다. 자료의 크기는 6으로 짝수이므로 중앙값은 5와 7의 평균값인 6이 된다. 이제 6 아래의 자료들인 (1,3,5)에 대해 다시 중앙값을 구해준다. 아래 부분의 중앙값은 3이므로 fivenum()을 통한 y의 제1사분위수는 3이다.
이번에는 summary()로 제1사분위수를 구해보자. 제1사분위수는 25% quantile이다. 25% quantile의 위치는 1+(6-1)*25/100=2.25이다. j=2.25이므로 i=2, k=3이다. 자료의 i번째 값은 3, k번째 값은 5이다. 따라서 위의 계산방법에 따라 25% quantile은 3+(2.25-2)(5-3)=3.5이다.
결론적으로 두 함수의 차이는 평균값의 반환여부와 사분위수의 계산 방법에 있다. 사분위수 계산 방법의 차이 때문에 자료의 크기가 짝수일 때는 제1사분위수와 제3사분위수 계산값이 다르게 나온다. 하지만 자료의 크기가 홀수일 경우에는 사분위수 계산 결과가 동일하게 도출된다.
R의 패키지는 분석 함수뿐 아니라 예제 데이터도 포함하는 경우가 많다. 이 데이터를 패키지 데이터셋이라고 한다. 보통 R을 시작하면 datasets라고 하는 패키지가 자동으로 로드되는데 이 패키지는 기본적인 예제 데이터셋만을 포함하고 있는 패키지이다.ToothGrowth 데이터셋은 이 패키지에 포함되어 있기 때문에 ToothGrowth이라는 명령어로 바로 불러올 수 있다.
ToothGrowth 데이터셋에 대한 설명은 ?ToothGrowth라는 명령어를 통해 확인할 수 있다. 데이터셋의 설명은 다음과 같다.
The Effect of Vitamin C in Tooth Growth in Guinea Pigs
비타민C의 복용량에 따른 이의 성장을 확인하기 위해 다음과 같은 상자그림을 그릴 수 있다. 자료의 용이한 비교를 위해 notch를 적용하여 상자그림을 그렸다. 비타민C 복용량 0.5에 대한 상자의 크기는 대략 7에서 13이다. 복용량 1에 대한 상자의 크기는 대략 16에서 23이며, 복용량 2에 대한 상자의 크기는 대략 23에서 27이다. 복용량이 증가할수록 이의 성장이 두드러지게 증가함을 확인할 수 있다.
통계적으로 좀 더 유의미한 결론을 내리기 위해 상자의 notch를 확인한다. 상자그림에서 notch는 각각의 상자에서 안쪽으로 꺾이는 범위를 통해 확인할 수 있다. notch는 EDA에서 사용하는 robust한 신뢰구간으로 중앙값에 대한 95% 신뢰구간을 계산한다. 비교하는 대상의 notch의 범위가 중첩하지 않는다면 대략 95%의 유의수준에서 두 자료는 유의미한 차이가 있다고 결론내릴 수 있다.
먼저 복용량 0.5와 1의 상자를 보자. 전자의 notch는 대략 8에서 12, 후자의 notch는 대략 17에서 22이다. 두 개의 notch는 서로 중첩되지 않으며 따라서 두 복용량에 대한 이의 성장은 대략 95%의 유의수준에서 유의미한 차이가 있다고 말할 수 있다. 이번에는 복용량 1과 2의 상자를 보자. 역시 두 개의 notch는 서로 중첩되지 않으며 따라서 두 복용량에 대한 이의 성장은 대략 95%의 유의수준에서 유의미한 차이가 있다고 말할 수 있다. 따라서 0.5에서 2로의 복용량의 증가는 이의 성장에 양의 방향으로 유의미한 영향력을 미친다고 해석할 수 있다.
위에서 비타민C의 복용이 이의 성장에 유의미한 영향이 있음을 확인했다. 하지만 ToothGrowth 자료는 비타민C를 오렌지 주스로 섭취했는지 혹은 아스코르브 산으로 섭취했는지에 대한 정보도 포함하고 있다. 이 정보를 활용하여 위와 같은 상자그림을 그릴 수 있다. 각각의 복용량에 대하여 오렌지 주스로 섭취한 자료와 아스코르브 산으로 섭취한 자료를 색을 달리하여 한 그림에 표현했다. 복용량 0.5와 2에서는 섭취방법에 따른 유의미한 차이는 없는 것으로 나타났다. 복용량 0.5와 2에서의 상자들을 살펴보면 각각의 notch들이 서로 중첩되는 것을 확인할 수 있다. 반면 복용량 1에서는 섭취방법에 따른 notch가 서로 중첩되지 않는다. 아스코르브 산의 notch는 대략 14에서 16이며 오렌지 주스의 notch는 대략 19에서 26이다. 따라서 비타민C 복용량 1에서는 95%의 유의수준에서 섭취방법에 따른 이의 성장에 유의미한 차이가 있다고 말할 수 있다.
추가적으로 비타민C 복용량과 이의 성장의 상관관계 분석을 수행할 수 있다. 상관관계 분석은 인과관계를 설명하지는 않지만 두 변수 간에 얼마만큼의 상관성이 있는지를 파악할 수 있는 간단하면서도 강력한 분석 기법이다.
cor.test(ToothGrowth$len, ToothGrowth$dose)
##
## Pearson's product-moment correlation
##
## data: ToothGrowth$len and ToothGrowth$dose
## t = 10.25, df = 58, p-value = 1.233e-14
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
## 0.6892521 0.8777169
## sample estimates:
## cor
## 0.8026913
분석 결과, 피어슨 상관계수는 약 0.8027이 나왔으며 p값이 매우 작아 귀무가설을 기각했다. 즉 비타민C 복용량과 이의 성장 사이에 양의 상관관계가 있다는 것이다. 상자그림을 통해서 눈으로 확인한 정보를 가설 검정으로도 살펴보았다.
airquality는 다음의 정보를 갖는 데이터프레임이다. 데이터셋에 대한 설명은 ?airquality라는 명령어를 통해 확인할 수 있다.
New York Air Quality Measurements
fivenum(airquality$Ozone)
## [1] 1.0 18.0 31.5 63.5 168.0
Ozone의 다섯 수치 요약을 fivenum()으로 수행했다. 먼저, 자료의 중앙값은 31.5이다. 자료의 범위는 최소값과 최대값의 차이로 확인할 수 있는데 167이다. 중앙값과 최소값의 차이는 30.5이며 중앙값과 최대값의 차이는 136.5이다. 따라서 자료의 분포가 오른쪽으로 길게 늘어진 모양을 하고 있음을 추측할 수 있다. 중앙값 아래 부분인 1부터 31.5까지의 범위에 자료가 몰려있을 것이다.
상자그림을 확인할 수 있는 Ozone 자료의 분포는 위와 같다. 다섯 수치 요약에서 확인했듯이 낮은 값에서 자료의 밀도가 높음을 확인할 수 있다. 중앙값은 상자의 약간 아래쪽에 위치하고 있으며 상자의 수염은 자료의 높은 값으로 길게 뻗어있다. 다섯 수치 요약에서 확인할 수 없었던 자료는 특이값이다. 상자그림을 통해서 두 개의 특이값을 발견했다.
바람이 7mph미만과 7mph이상으로 불 때의 Ozone의 상자그림을 위와 같이 그렸다. 각각의 상자의 범위는 50에서 100, 20에서 40 정도로 중첩되지 않는다. 중앙값에도 선명한 차이가 있어보인다. 다만, 상자의 수염의 범위는 10에서 80까지 중첩되어 상당히 넓은 범위가 중복된다. 이는 오존량에 바람 이외에 다른 다양한 변수가 영향을 미치기 때문으로 추측된다. 바람 외에도 오존량에 영향을 미치는 다른 변수들을 살펴볼 필요가 있다.
통계적으로 좀 더 유의미한 결론을 내리기 위해 상자의 notch를 확인한다. 상자그림에서 notch는 각각의 상자에서 안쪽으로 꺾이는 범위를 통해 확인할 수 있다. notch는 EDA에서 사용하는 robust한 신뢰구간으로 중앙값에 대한 95% 신뢰구간을 계산한다. 비교하는 대상의 notch의 범위가 중첩하지 않는다면 대략 95%의 유의수준에서 두 자료는 유의미한 차이가 있다고 결론내릴 수 있다.
확인 결과, 각각의 notch는 중첩되지 않는다. 따라서 7mph 이상의 바람은 오존량에 음의 방향으로 유의미한 변화를 가져온다고 대략 95%의 유의수준으로 결론내릴 수 있다.
상자그림의 장점은 대략적인 정보를 한눈에 확인할 수 있다는 점이다. 하지만 상자의 크기나 중앙값 등의 정확한 수치를 눈대중으로 확인할 수 밖에 없다. 가령 7mph 이상의 바람이 불 때의 오존량의 중앙값은 대략 20과 30 사이에 존재하지만 우리는 그 정확한 수치를 상자그림을 통해서는 확인할 수 없다. 따라서 이번에는 문자값전시를 이용하여 자료를 살펴보도록 하자. R에는 문자값전시를 위한 코드가 따로 존재하지 않으나 아래의 링크를 통해 누군가가 만들어놓은 함수를 불러와 활용할 수 있다.
# 7mph 미만 바람에서의 오존량 문자값전시
source("http://mgimond.github.io/ES218/es218.R")
lsum(airquality[airquality$Wind < 7,]$Ozone)
# 7mph 이상 바람에서의 오존량 문자값전시
lsum(airquality[airquality$Wind >= 7,]$Ozone)
문자값전시를 이해하기 위해서 먼저 맨 왼쪽의 letter를 이해해야한다. M은 median, H는 hinges, E는 eighths, D는 sixteenths를 의미한다. 상자그림과 달리 문자값전시에서는 각각의 정확한 값을 확인할 수 있다. 7mph 이하 바람에서의 오존량의 중앙값은 78, 7mph 이상 바람에서의 오존량의 중앙값은 23이다. 이외에도 upper hinge 혹은 lower hinge 등의 값들도 확인 가능하다.
문자값전시에서 확인할 수 있는 대표적인 정보는 왜도와 첨도이다. 왜도는 mid값의 변화를 통해, 첨도는 spread의 변화를 통해 파악할 수 있다. 먼저 7mph 미만 바람에서의 오존량 문자값전시를 보자. mid가 78에서 74까지 감소했다가 다시 81.5까지 상승했다. mid값의 변화량이 크지 않으므로 왜도의 정도가 심하지 않을 것이라 추측할 수 있다. 반면 7mph 이상 바람에서의 오존량 문자값전시를 살펴보자. mid값의 변화가 23에서 꾸준히 증가하여 46.75까지 올라갔다. 이는 자료의 분포가 오른쪽으로 길게 뻗은 모양일 때 나타나는 현상이다. 실제로 아래의 히스토그램을 보면 자료의 분포가 양의 왜도임을 확인할 수 있다.
첨도는 spread의 변화를 통해 확인할 수 있다. spread의 증가 속도가 빠를수록 더 뾰족한 모양을 갖는 분포가 된다. 첨도의 계산은 H-spread와 E-spread의 비로 측정하는데 7mph 미만에서의 E/H의 비율값은 88/43=2.047, 7mph 이상에서의 E/H 비율값은 52/27=1.926이다. (정확한 첨도는 이 값에 정규분포의 첨도값을 빼야 하지만 비교를 위해 단순히 계산했다.)따라서 7mph 미만에서의 첨도가 더 크므로 더 뾰족한 분포를 가져야 한다. 하지만 실제 아래의 히스토그램을 살펴보면 그렇지 않다는 것을 확인할 수 있다. 첨도는 상당히 불완전한 통계량이기 때문에 여러 검증을 거치며 주의해서 사용해야 한다.
온도 80도 미만과 80도 이상일 때의 Ozone의 상자그림을 위와 같이 그렸다. 각각의 상자의 범위는 20에서 30, 40에서 80 정도로 중첩되지 않는다. 중앙값에도 선명한 차이가 있어보인다.
통계적으로 좀 더 유의미한 결론을 내리기 위해 상자의 notch를 확인한다. 상자그림에서 notch는 각각의 상자에서 안쪽으로 꺾이는 범위를 통해 확인할 수 있다. notch는 EDA에서 사용하는 robust한 신뢰구간으로 중앙값에 대한 95% 신뢰구간을 계산한다. 비교하는 대상의 notch의 범위가 중첩하지 않는다면 대략 95%의 유의수준에서 두 자료는 유의미한 차이가 있다고 결론내릴 수 있다.
확인 결과, 각각의 notch는 중첩되지 않는다. 따라서 80도 이상의 온도는 오존량에 양의 방향으로 유의미한 변화를 가져온다고 대략 95%의 유의수준으로 결론내릴 수 있다.
상자그림의 장점은 대략적인 정보를 한눈에 확인할 수 있다는 점이다. 하지만 상자의 크기나 중앙값 등의 정확한 수치를 눈대중으로 확인할 수 밖에 없다. 따라서 이번에는 문자값전시를 이용하여 자료를 살펴보도록 하자.
# 80도 미만 온도에서의 오존량 문자값전시
lsum(airquality[airquality$Temp < 80,]$Ozone)
# 80도 이상 온도에서의 오존량 문자값전시
lsum(airquality[airquality$Temp >= 80,]$Ozone)
문자값전시를 통해 자료의 왜도와 첨도를 각각 확인할 수 있다. 왜도는 mid값의 변화를 통해, 첨도는 spread의 변화를 통해 파악할 수 있다. 먼저 온도 80도 미만의 오존량 문자값전시를 보자. mid가 20에서 28로 증가한다. mid값의 증가는 자료의 분포 모양이 오른쪽으로 길게 뻗어있다는 의미이다. 온도 80도 이상의 자료에서도 mid값의 변화가 63에서 꾸준히 증가하여 70.5까지 올라갔다. 역시 양의 왜도를 갖는다. 실제로 아래의 히스토그램을 보면 자료의 분포가 양의 왜도임을 확인할 수 있다.
첨도는 spread의 변화를 통해 확인할 수 있다. spread의 증가 속도가 빠를수록 더 뾰족한 모양을 갖는 분포가 된다. 첨도의 계산은 H-spread와 E-spread의 비로 측정하는데 80도 미만에서의 E/H의 비율값은 28/15=1.867, 80도 이상에서의 E/H 비율값은 70/46=1.5217이다. 따라서 80도 미만에서의 첨도가 더 크므로 더 뾰족한 분포를 갖는다.
2000년과 2019년의 7개 광역시 구별 인구를 비교하기 위해 아래와 같은 상자그림을 그렸다. 시간에 따른 도시별 비교를 용이하게 하기 위해 하나의 그림에 두 시간대의 자료를 동시에 표시했다.
도시별 인구 변동 추이는 다음과 같다.
광주 : 먼저 중위값을 살펴보면 2000년에 비해 2019년의 중위값이 크다. 2000년 상자의 길이는 상대적으로 짧다. 상자그림에서 상자는 IQR, 즉 자료의 산포를 의미한다. 이는 2000년의 광주광역시의 구별 인구가 비슷했다는 의미이다. 다만, 상자 위아래로 특이값을 확인할 수 있다. 위 특이점은 광주 북구의 자료이며, 아래 특이점은 광주 동구의 자료이다. 2000년의 광주는 북구와 동구를 제외한 나머지 구들의 인구 수가 비슷하며 북구에 유독 많은 인구가 거주했다. 2019년의 상자그림은 상자의 길이가 길어졌으며 특이값이 사라졌다. 인구 수 자료의 산포가 커졌다는 의미이다. 즉 광주광역시의 구별 인구에 차이가 심해졌다는 것이다. 상자그림만 봐서는 위와 같은 결론을 내릴 수 있지만 우리는 광주광역시의 구가 5개 뿐이라는 것에 주목해야한다. 사실상 2000년 상자그림의 특이값의 범위와 2019년 상자그림의 수염의 범위는 비슷하다. 특이값이 사라진 이유는 특이값을 결정하는 기준인 H-spread(상자의 길이)가 커져서이다. 즉 양 극단에 위치한 자료의 값들은 거의 비슷한 범위로 떨어져 있으며 중간의 세 구의 인구 수의 산포가 커진 것이다. 광주는 지난 20년간 구별 인구 격차가 심해졌다.
대구 : 대구광역시는 중위값의 하락과 함께 상자가 아래쪽에 위치한다. 전체적으로 모든 구에서 인구의 감소가 발생했다. 상자의 길이는 비슷하여 상자 내부의 구별 인구 격차는 변동하지 않았다. 하지만 2019년의 상자의 수염을 살펴보면 위쪽으로 길게 뻗어있는 것을 확인할 수 있다. 이는 특정 몇 구에 인구가 집중되어 있고 나머지 구에서는 인구가 적게 거주함을 의미한다.
대전 : 대전광역시는 전체적으로 광주광역시와 비슷한 인구 변동 추이를 갖는다. 2000년 자료에서 두 개의 특이값이 발견되며, 이 두 구를 제외한 나머지 구에서는 인구 격차가 거의 없다. 광주와 비슷하게 2019년에서는 상자의 길이가 길게 변한다. 구별 인구 격차가 심해진 것이다. 2019년에도 유독 값이 큰 하나의 특이값이 발견되는 것으로 보아 한 개의 구에 인구가 집중되었음을 확인할 수 있다. 다만 전체적으로 모든 구에서 인구의 감소가 크게 일어났으며 아래 특이값이 사라졌다. 중위값의 큰 하락을 확인할 수 있다. 지난 20년간 지속적인 인구 유출이 있었던 것으로 추정된다.
부산 : 부산광역시의 각 구의 인구 수 분포는 하나의 특이값을 제외하면 큰 차이가 없다. 중위값에 약간의 하락이 있지만 전체적인 상자의 길이와 수염의 길이가 비슷하다. 즉 자료의 산포에는 큰 변화가 없었으며 이는 구별 인구 격차가 비슷하게 유지되었다는 것을 의미한다. 하지만 2019년 자료에서 멀리 떨어진 특이값이 하나 발생했다. 특정한 한 구에서 인구가 폭발적으로 증가한 것이다. 하나의 구에서 큰 발전이 있었고 나머지 구에서는 별다른 변화가 없었음을 유추할 수 있다.
서울 : 서울특별시의 인구 변동 추이는 부산과 비슷하다. 전체적으로 2000년과 2019년의 큰 차이가 보이지 않는다. 2000년 자료에서 보였던 아래의 특이값 두 개가 2019년의 자료에서는 보이지 않는데 이는 두 값이 상자의 수염에 포함되었기 때문이다. 인구 수로 중간 즈음에 있는 구들에서 인구 격차가 조금 심해져 상자의 길이가 조금 늘어났다. 특이값의 결정은 H-spread(상자의 길이)를 기준으로 하기 때문에 2019년의 늘어난 H-spread 때문에 두 개의 특이값이 사라진 것이다. 중위값에 약간의 상승이 있지만 큰 차이는 아닌 것으로 보인다.
울산 : 울산광역시의 자료에서는 중위값의 상승과 함께 상자의 길이가 길어졌다. 울산 역시 광주와 동일하게 구가 5개 뿐이다. 즉 수염의 길이가 비슷한 것으로 보아 최대 인구와 최소 인구를 갖는 두 개의 구는 2000년이나 2019년이나 비슷하게 떨어져있으며 가운데를 구성하는 세 개의 구에서 인구 격차가 심해졌다. 물론 여기서 가운데를 구성하는 세 개의 구는 2000년과 2019년에 각각 다르다.
인천 : 인천광역시는 구별 인구 격차가 가장 심한 도시이다. 2000년과 2019년 모두 수염의 범위가 대략 10000에서 500000으로 상당히 범위가 넓다. 절대적인 중위값이 낮아지고 상자에서 중위값의 위치도 아래로 이동했다. 즉 2000년 자료에 비해 2019년의 인천광역시 자료는 오른쪽으로 길게 늘어진 분포의 모양을 갖는다. 이는 특정 구로의 인구 집중이 심해졌음을 의미한다.
보고서에 쓰인 모든 코드를 아래에 정리해두었다.
## R script
#1.
x = seq(1, 9, by=2)
x
fivenum(x)
summary(x)
y = seq(1, 11, by=2)
y
fivenum(y)
summary(y)
#2.
boxplot(len ~ dose, data = ToothGrowth, xlab = "Amount of Dose", ylab = "Length of Odontoblasts",
main = "ToothGrowth", notch=T, col="papayawhip")
boxplot(len ~ dose, data = ToothGrowth, boxwex = 0.25, at = 1:3 - 0.2,
col = "papayawhip", main = "Tooth Growth",subset = supp == "VC",
xlab = "Amount of Dose", ylab = "Length of Odontoblasts",
xlim = c(0.5, 3.5), ylim = c(0, 35), notch=T, xaxt = "n")
boxplot(len ~ dose, data = ToothGrowth, add = TRUE,
boxwex = 0.25, at = 1:3 + 0.2,
subset = supp == "OJ", col = "peachpuff2", notch=T, xaxt = "n")
axis(side = 1, labels = c("0.5", "1", "2"), at = 1:3)
legend(2.5, 7, c("Ascorbic acid", "Orange juice"), fill = c("papayawhip", "peachpuff2"))
#3.
#3-1.
fivenum(airquality$Ozone)
boxplot(airquality$Ozone, main="Boxplot of Ozone", col="papayawhip")
#3-2.
airquality[airquality$Wind >= 7,"Wind_7"] = "Over than 7"
airquality[airquality$Wind < 7,"Wind_7"] = "Less than 7"
boxplot(Ozone ~ Wind_7, data=airquality, xlab="Wind", main="Boxplot of Ozone by Wind", col="papayawhip", notch=T)
source("http://mgimond.github.io/ES218/es218.R")
lsum(airquality[airquality$Wind < 7,]$Ozone)
lsum(airquality[airquality$Wind >= 7,]$Ozone)
par(mfrow=c(1,2))
hist(airquality[airquality$Wind < 7,]$Ozone, main="Hist of Ozone(Wind less than 7mph)", xlab="Ozone", col="papayawhip", xlim=c(0,200), ylim=c(0,25), breaks=10)
hist(airquality[airquality$Wind >= 7,]$Ozone, main="Hist of Ozone(Wind over than 7mph)", xlab="Ozone", col="papayawhip", xlim=c(0,200), breaks=10)
#3-3.
airquality[airquality$Temp >= 80,"Temp_80"] = "Over than 80"
airquality[airquality$Temp < 80,"Temp_80"] = "Less than 80"
par(mfrow=c(1,1))
boxplot(Ozone ~ Temp_80, data=airquality, xlab="Temperature", main="Boxplot of Ozone by Temperature", col="papayawhip", notch=T)
lsum(airquality[airquality$Temp < 80,]$Ozone)
lsum(airquality[airquality$Temp >= 80,]$Ozone)
par(mfrow=c(1,2))
hist(airquality[airquality$Temp < 80,]$Ozone, main="Hist of Ozone(Temp less than 80)", xlab="Ozone", col="papayawhip", xlim=c(0,200), breaks=10, ylim=c(0,25))
hist(airquality[airquality$Temp >= 80,]$Ozone, main="Hist of Ozone(Temp over than 80)", xlab="Ozone", col="papayawhip", xlim=c(0,200), breaks=10, ylim=c(0,25))
#4.
old = read.csv("광역시-구 인구(2000).csv")
new = read.csv("광역시-구 인구(2019).csv")
par(mfrow=c(1,1))
boxplot(인구~지역명, data=old, boxwex = 0.25, at = 1:7 - 0.2,
col="papayawhip", xlim=c(0.5,7.5), ylim=c(0,700000), xaxt = "n")
boxplot(인구~지역명, data=new, boxwex = 0.25, at = 1:7 + 0.2,
col="peachpuff2", add=TRUE, xaxt = "n")
title("광역시의 구별 인구 비교")
axis(side = 1, labels = c("광주", "대구", "대전", "부산", "서울", "울산", "인천"),
at = 1:7)
legend(0.5, 685000, c("2000", "2019"), fill = c("papayawhip", "peachpuff2"))