*참고자료: introductory statistics with R, 기타 블로그 및 R 개론서
* 한마디
* 범위: chapter 4 descriptive statistics 기술통계학
실제 데이터 분석에 앞서 자료의 특성을 살펴보는 것은 매우 중요함.
* Summary statistics for a single group: 단일 그룹에 대한 통계 수치들 요약
일반적인 통계 수치 인 mean, sd, variance, median은 다음 함수로 간단이 구할 수 있다.
mean(), sd(), var(), median()
단, 이 때 결측치가 있다면 모든 결과는 NA로 출력되므로 na.rm=T 로 제거해줘야 적절한 결과를 얻을 수 있음.
sum()
변수 내 데이터의 합을 구해줌. 결측치 제거를 하고 연산결과를 보기 위해선 na.rm=TRUE를 해줘야 함.
변수 내 데이터의 개수를 보는 함수는 length()가 있는데, 결측치 여부를 0, 1로 return해주는 is.na() 함수와 sum 함수를 이용하면 결측치/결측치가 아닌 데이터의 총 개수를 구할 수 있다.

quantile()
사분위수를 반환함. min(0%), 0.25 quantile(25%), median(50%), 0.75 quantile(75%), max (100%)
second argument로 원하는 percentage point를 넣으면 10분할 등 원하는 만큼 분할할 수 있다.

summary()
전체 데이터의 포괄적 통계 수치를 data frame으로 반환함.

이 때 sex나 menarche, tanner 등 범주형 자료를 숫자로 코딩해넣은 경우 numerical variable처럼 통계를 내버린다.
따라서 이를 factor로 바꿔주어 summary()를 실행시키면 다른 결과를 볼 수 있다.

transform()이나 within() 명령어를 써도 동일하게 수정이 가능하다.
** 잘 이해가 안가는 부분

* Graphic display of distribution 분포를 그림으로 나타내기
* Histogram
hist()
breaks=c() argument를 이용해 histogram의 cut point를 지정할 수도 있다.
freq=T/F argument에서, T를 선택할 경우 실제 count가 / F를 선택하는 경우 density가 표시된다.
* Empirical cumulative distribution (ECD)

정의는 "the fraction of data smaller than or equal to x" 이다. 풀어서 얘기하자면 n의 크기를 갖는 데이터 샘플에 대해, 각각의 항목에 1/n의 확률을 배당한다. 그리고 데이터를 sort 해서 내림차순으로 정렬한 뒤, 자료가 작은 순으로 하나씩 plot을 진행하며, 자료의 순서가 하나씩 진행됨에 따라 plot의 y축 값을 1/n씩 높이는 것이다. 즉, k번째로 작은 자료 Xk의 좌표는 (Xk, k/n)이 될 것이다. 이 개념을 그대로 적용하면 아래와 같은 코드가 나온다.

좀 더 섬세한 ecd 그래프를 그리기 위해선 ecdf 함수를 사용하면 된다. (stats library를 사용해야 함)
* Q-Q plot
데이터가 정규분포를 하는지 시각적으로 확인하는 방법. 데이터를 오름차순으로 sorting한 다음, k번째 plot의 Y축 값은 데이터의 k번째로 작은 값을 사용한다. 데이터와 size가 같은, 정규분포를 따르는 집단을 추출한 뒤 이들을 오름차순으로 sorting한다. 그리고 k번째 plot의 X축 값으로 사용한다. 즉, k번째 plot의 좌표는 (Xk, Yk) while X~ N(mu, sigma^2)가 될 것이다. 만약 데이터의 분포가 정규분포에 가깝다면 데이터 사이의 간격 분포는 정규분포인 Y와 유사할 것이다. 따라서 y=x의 그래프를 근사적으로 따르는 모양으로 그려질 것이다.

코드를 풀어서 짜자면 plot(sort(rnorm(length(a))),sort(a)) 의 형태가 되겠지만 간단한 qqnorm() 명령어 하나로 실행이 가능하다. ECD와 다른 점은, x축과 y축이 반대라는 점이다. 즉, ECD는 X축이 실제값 - Y축이 예측값이라면 QQ plot은 X축이 이론값이고 Y축이 실제값이다.
* Boxplot
plot() 명령으로 그래프를 그리면 배번 새로운 창이 뜨면서 그래프가 그려짐. 이 때 par(mfrow=c(nr,nc)) 를 사용하면 한 창에 여러 개의 그래프를 나열할 수 있음. 마지막에 par(mfrow=c(1,1))를 사용해 기존의 설정으로 되돌려야 한다.

혹은, opar 이라는 변수를 써서 보통 쉽게 이를 되돌리는데 이에 대해 아래 코드를 보며 자세히 알아보자.

언뜻 보면 opar에는 par(mfrow=c(1,2))라는 함수가 저장된 것 처럼 보인다. 그런데 par(opar)를 하면 마치 par(mfrow=c(1,1))를 시행한 것 같은 초기화 효과를 보인다. 이는 par 함수의 특수성 때문으로 보이는데, par 함수는
1) 호출되는 순간, plot에 대한 정보를 변경한다: 즉, opar에 par 함수값을 할당하는 것 처럼 코딩을 작성했지만 실제로는 par(mfrow=c(1,2))를 단독으로 호출한 것과 동일한 결과를 얻는다. 즉, 그래프가 2 column으로 출력되도록 설정된다.
2) 그렇다면 opar에는 어떤 값이 할당되는가? par(arg) 함수의 특성은, 언급된 argument의 기본값만을 리턴하는 것이다. 즉, par(mfrow=c(nr,nc))에 어떤 값이 입력되든 opar에는 mfrow=c(1,1) 값이 입력된다. par()에는 mfrow 이외에도 수많은 argument들이 존재하며, 빈 변수에 par()를 할당해보면 이 리스트를 얻을 수 있다. par() 함수는 모든 argument에 대해 동일한 기능을 하는 것으로 보인다. 이 중 우리가 특정 argument를 넣어 조건을 설정하는 경우, opar과 같이 할당된 변수에 입력되는 값은 해당 argument의 "기본값"이다.
다소 복잡하긴 하지만, 아마 par() 함수의 제작자가 위의 용례와 같이 이용하기 최적의 상태로 함수를 세팅한 것이 아닌가 싶음. 그냥 opar <- par(arg), par(opar)를 coupling 해서 알아두고 사용하면 되겠다.
* Summary statistics by group: 그룹별로 요약 통계치 구하기
보통 여러 그룹을 포함하는 데이터셋을 분석할 때, 전체 자료 뿐 아니라 각각의 그룹 별 통계값을 구하고 이를 비교해야 하는 경우가 많다. 이 때 사용할 수 있는 함수가 tapply() 함수이다. (chapter 1 정리 참고:insb.tistory.com/9)
tapply는 다음과 같이 사용한다: tapply(데이터, index(=factor), function)

물론 이 때에도 결측치가 문제가 된다면 na.rm=T를 사용한다.
비슷한 함수로 aggregate, by 함수가 있다.
aggregate()
다음과 같이 사용한다: aggregate(data, grouping argument, function, ...)
이 때 중요한 점은 다음과 같다.
1) grouping argument가 반드시 '리스트'로 제공되어야 한다는 것이다. 보통 list(name=value) 형식으로 입력.
2) 기본적으로 전체 data에 대해 적용된다. 따라서 data의 subset을 넣거나 전체에 적용한 뒤 subset을 추려내는
방식으로 이용할 수 있다.

by()
다음과 같이 사용한다: by(data, grouping argument, function)

by 함수의 결과값은 'by'라는 객체로, list 자료형을 묶어놓은 것이다. 따라서 list indexing을 이용하면 원하는 자료의 부분만을 이용할 수 있음.
위의 aggregate나 tapply와 다른 점은, 직접 summary를 앞의 두 함수에 넣어서 적용해보면 느끼겠지만, 각각의 grouping argument 값에 대해 list를 생성해주므로 전체 데이터에 summary를 적용시켰을 때 데이터를 보기 훨씬 좋다.
* Graphics for grouped data: 그룹 별 자료의 시각화
자료 간 비교를 용이하기 위해 자료를 그룹 별로 시각화할 수 있다.
* Histogram


* Parallel boxplot
같은 frame에 group 별로 boxplot을 그려 서로 비교해볼 수 있음.
boxplot(data ~ factor)
위 함수를 사용하면 data를 factor에 따라 group으로 묶고, 이를 boxplot으로 표시해 비교한다.
(본문 인용: Notation of the type y~x should be read "y describing using x")

만약, obese / lean 두 그룹으로 나눠진 expend라는 데이터를 위와 같이 시각화 하려면, 다음과 같이 풀어서 쓸 수도 있을 것이다.
boxplot(expend[stature=="lean"],expend[stature=="obese"])
* Stripchart
데이터의 size나 특성에 따라, boxplot처럼 quartile를 나타내는 것은 부정확할 수 있다. (특히 size가 작은 경우, quartile은 너무 클 수 있어 데이터 범위를 과장되게 나타냄) 따라서 작은 group은 raw data를 직접 plot해 비교하는 것이 좋으며, 이는 stripchart를 이용하면 가능하다.

par의 argument는 아래에서 설명. stripchart의 특성을 보면 아래와 같다.
1) parallel boxplot처럼 data ~ factor 의 구조를 이용한 그룹 간 비교가 가능하다.
2) method 에서 stack은 동일한 값이 있을 경우 위로 쌓아서(stack) 표시한다. 위이 그래프에서는 stack이 lean 그룹에
딱 한개 보이는데, 이 이유는 유사한 값이 아닌 정확히 동일한 값이여야 stack이 되기 때문.
3) method에서 jitter를 사용하면 각 값들을 random하게 조금 흩어놓아 표시한다. 따라서 비슷한 위치에 있는 점들이
겹쳐 보이는걸 방지할 수 있음. jutter argument를 이용해 흔들림 정도를 보정할 수도 있다. 기본값은 0.1이다.
par 함수를 사용할 때, mex는 plot들 사이의 거리를 의미하며, mar는 plot 내에서 margin 거리를 의미한다.
기본값은 mex=1, mar=c(5,4,4,2)+0.1 이다.


* Tables
범주형 자료들은 주로 table로 많이 표시하고 비교하게 된다. Table을 만들고 상대빈도를 구하는 법을 알아보자.
* Generating tables
가장 많이 사용하는 기본 table은 two-way table이다. Table은 "table"이라는 별개의 class가 있으며, 데이터 입력 시에는 직관적인 matrix를 이용해 생성한 후 as.table 명령어 등을 통해 변경할 수 있다. Matrix 명령어는 chapter 1 참조.
(insb.tistory.com/9?category=967351)
참고로, table 객체 역시 matrix와 마찬가지로 t() 명령어로 transpose (전치행렬: 행-렬 바꾸기)를 할 수 있다.
Matrix를 as.table로 table 객체로 만든 다음, 다시 as.data.frame()를 이용해 data frame으로 만든다면 각각의 table 요소 조합에 대한 frequency가 자동으로 계산되어 표시된다. Matrix를 곧바로 as.data.frame()으로 바꾸면 동일한 형태를 가진, class만 다른 data frame이 형성되지만 table로 변경했다 다시 dat frame으로 변경하는 경우는 전혀 다른 결과가 나온다.

Table(factor1, factor2, ...) 함수는 범주형 변수의 수를 count해서 분류표를 만들어주는 함수이다. 입력하는 factor의 수에 따라 one, two, three way 등의 table을 만들 수 있으나 일반적으로는 two way를 제일 많이 쓴다.
xtabs() 함수는 table과 거의 비슷하나 사용 방법이 좀 다름.
xtabs(~ factor1 + factor2 + .. , data=데이터)
데이터를 지정한 후 그 내부의 factor들을 $기호 없이 이용할 수 있다. 즉, attach()하지 않고도 비교적 편하게 변수명을 이용할 수 있다는 장점.
ftable()은 "flat table"들어준다. Flat table은 2차원 이상의 table을 다룰 때 유용하다.

* Marginal tables and relative frequency
Marginal table이란, 간단히 말하면 dimension을 축소한 것이다. 즉, 하나의 분류는 유지한 채로 나머지 factor의 도수들을 모두 합해 나타낸 것이다. apply() 함수를 이용할 수도 있으나, margin.table()함수를 이용하면 간단히 구할 수 있다.
margin.table(table, 방향)
방향은 1인 경우 row 방향의 합을, 2인 경우는 column 방향의 합을 구해준다.

prop.table(table, 방향)
Table 각각의 도수를 상대도수로 표현해준다. 이 때, 방향은 1인 경우 row의 합이 1, 2인 경우 column의 합이 1이 되도록 확률을 구성한다.

prop.table에 방향 지정이 따로 없다면 전체 확률 합이 1이 되도록 구성한다. 또는, 단순하게 전체 도수의 합으로 table을 나눠주는 연산을 하면 이를 동일하게 구할 수 있다. table/sum(table)

* Graphical display of tables
테이블을 시각화하는 방법에 대해 알아보자.
* Barplot
아래 그림을 살펴보면 table의 barplot이 어떻게 구성되는지 볼 수 있다.

Two-way table로 barplot을 시행하면, 가장 기본적인 형태는 각각의 column에 대해서 barplot이 만들어지며 row에 따른 그룹 구분은 barplot 내부에 구분선을 만들어 구부해준다. ("Stacked barplot"이라고 함)
t()를 이용해 전치행렬을 구한 뒤, 이를 입력해주면 행-열이 뒤바뀐 결과를 얻을 수 있다.
beside=T argument를 이용하는 경우엔 stacked barplot이 아닌, 각 group들을 옆으로 나란히 배열해준다.
마지막으로 prop.table을 사용한느 경우 각각을 전체 도수가 아닌 비율로 나타내준다. 방향이 2이므로 column 내 합이 1이 되는, 즉 그룹 내 barplot들을 더하면 모두 1이 되는 구조이다.

좀 더 보기 좋은 barplot을 만들기 위해 legend를 삽입하였고, col에 vector를 넣어 각 barplot에 색을 지정하였다.
Legend 관련은 chapter 2 참조(insb.tistory.com/13?category=967351), 화면 상의 정확한 (x,y) 좌표값을 알고 싶다면 locator() 함수를 사용하면 된다. locator() 함수 사용 이후 마우스로 click한 지점은 모두 저장되어 ESC 누른 이후 list 값으로 반환된다.
* Dotcharts
Cleveland dotchart는 barplot과 동일한 정보를 포함하지만, 점을 찍어 표현한다는 점에서 모양은 다르다.

* Piecharts
파이차트는 전통적으로, 의미가 적은 데이터로 큰 인상을 주고 인간이 해독하기 어려운 특징으로 인해 통계학에서는 부정적으로 생각되어 왔다. Barplot에 비해 추가적으로 얻을 수 있는 정보도 없다. 즉, 통계적으로 그다지 쓸모가 있진 않음. 하지만 여전히 R을 이용해 piechart를 그릴 수 있다.

'[학습] 데이터분석방법론: R' 카테고리의 다른 글
Introductory statistics with R: chapter 6 (0) | 2021.03.18 |
---|---|
Introductory statistics with R: chapter 5 (0) | 2021.03.17 |
Introductory statistics with R: chapter 3 (0) | 2021.03.14 |
Introductory statistics with R: chapter 2 (0) | 2021.03.11 |
Introductory statistics with R: chapter 1 (0) | 2021.03.07 |