범주형 변수

순동·2022년 2월 4일
0
  1. table()
> library(MASS)
> str(survey)

> levels(survey$Smoke)
[1] "Heavy" "Never" "Occas" "Regul"

> frqtab <- table(survey$Smoke)  # 빈도표
> frqtab
Heavy Never Occas Regul 
   11   189    19    17 
  1. 최빈값
> frqtab[frqtab == max(frqtab)]  # 최빈값
Never 
  189 

> names(frqtab[frqtab == max(frqtab)])  # 최빈값의 이름
[1] "Never"

> frqtab[which.max(frqtab)]  # 주어진 벡터의 최대값 위치를 인덱스로 반환
Never 
  189 
  1. prop.table()
> # 비율
> frqtab.prop <- prop.table(frqtab)

> frqtab.prop["Never"]
    Never 
0.8008475 

> frqtab.prop * 100  # 백분율

    Heavy     Never     Occas     Regul 
 4.661017 80.084746  8.050847  7.203390
> # 담배를 피우지 않는 사람의 비율
> mean(survey$Smoke == "Never", na.rm=T)
[1] 0.8008475

> # anorexia (식용부진증 환자 치료 전후의 몸무게 데이터셋)
> head(anorexia)
  Treat Prewt Postwt
1  Cont  80.7   80.2
2  Cont  89.4   80.1
3  Cont  91.8   86.4
4  Cont  74.0   86.3
5  Cont  78.1   76.1
6  Cont  88.3   78.1

> # 치료 후 몸무게가 증가한 식욕부진증 환자의 비율(치료 후 > 전)
> mean(anorexia$Postwt > anorexia$Prewt)
[1] 0.5833333

> # mammals (동물들의 두뇌의 무게)
> head(mammals)
                   body brain
Arctic fox        3.385  44.5
Owl monkey        0.480  15.5
Mountain beaver   1.350   8.1
Cow             465.000 423.0
Grey wolf        36.330 119.5
Goat             27.660 115.0

> # 두뇌의 무게가 상대적으로 크거나 작은 동물의 비율
> mean(abs(mammals$brain - mean(mammals$brain)) > 2*sd(mammals$brain))
[1] 0.03225806
  1. diff()
    연속된 두 숫자의 차이를 반환
> # SP500 (지수 수익률 일자별)
> head(SP500)
[1] -0.2588908 -0.8650307 -0.9804139  0.4504321 -1.1856666 -0.6629097

> # 수익률이 전일보다 증가한 일자의 비율(연속된 두 날짜의 수익률 차이가 0보다 큼)
> # 연속된 두 숫자의 차이를 반환 diff()

> mean(diff(SP500) > 0)
[1] 0.4857863

📌 교차표를 만드는 여러가지 방법들

  1. table()
> install.packages("vcd")
> library(vcd)

> head(Arthritis)
  ID Treatment  Sex Age Improved
1 57   Treated Male  27     Some
2 46   Treated Male  29     None
3 77   Treated Male  30     None
4 17   Treated Male  32   Marked
5 36   Treated Male  46   Marked
6 23   Treated Male  58   Marked

> str(Arthritis)
'data.frame':	84 obs. of  5 variables:
 $ ID       : int  57 46 77 17 36 23 75 39 33 55 ...
 $ Treatment: Factor w/ 2 levels "Placebo","Treated": 2 2 2 2 2 2 2 2 2 2 ...
 $ Sex      : Factor w/ 2 levels "Female","Male": 2 2 2 2 2 2 2 2 2 2 ...
 $ Age      : int  27 29 30 32 46 58 59 59 63 63 ...
 $ Improved : Ord.factor w/ 3 levels "None"<"Some"<..: 2 1 1 3 3 3 1 3 1 1 ...

> levels(Arthritis$Treatment)  # 의약/신약
[1] "Placebo" "Treated"

> levels(Arthritis$Improved)  # 치료 효과(없음/약간/많이)
[1] "None"   "Some"   "Marked"

> # Treatment 변수와 Improved 변수 간의 교차표(행, 열)
> crosstab <- table(Arthritis$Improved, Arthritis$Treatment)
> crosstab
        
         Placebo Treated
  None        29      13
  Some         7       7
  Marked       7      21

> crosstab["Marked", "Treated"]
[1] 21

> # table() 행과 열 이름 지정하여 교차표
> table(Arthritis$Improved, Arthritis$Treatment, dnn=c("Improved", "Treated"))
        Treated
Improved Placebo Treated
  None        29      13
  Some         7       7
  Marked       7      21
  1. xtabs()
    formula 인터페이스 방식으로 행과 열 변수 지정, formual의 오른쪽에 행과 열 변수를 +로 연결하여 지정
> crosstab2 <- xtabs(~ Improved + Treatment, data=Arthritis)
> crosstab2
        Treatment
Improved Placebo Treated
  None        29      13
  Some         7       7
  Marked       7      21
  1. margin.table()
    교차표 행과 열에 대한 빈도합
    margin.table(교차표, margin = 1(행) or 2(열)
> margin.table(crosstab, margin=1)
  None   Some Marked 
    42     14     28 

> margin.table(crosstab, margin=2)
Placebo Treated 
     43      41
> prop.table(crosstab, margin=1)  # 행의 합이 1이 되는 비율 교차표
        
           Placebo   Treated
  None   0.6904762 0.3095238
  Some   0.5000000 0.5000000
  Marked 0.2500000 0.7500000
> prop.table(crosstab, margin=2)  # 열의 합이 1이 되는 비율 교차표
        
           Placebo   Treated
  None   0.6744186 0.3170732
  Some   0.1627907 0.1707317
  Marked 0.1627907 0.5121951
> # 교차표 상의 개별 셀의 비율
> # prop.table() 함수의 margin 인수에 아무것도 지정하지 않고 교차표만 지정함

> prop.table(crosstab)
        
            Placebo    Treated
  None   0.34523810 0.15476190
  Some   0.08333333 0.08333333
  Marked 0.08333333 0.25000000
> prop.table(crosstab)
        
            Placebo    Treated
  None   0.34523810 0.15476190
  Some   0.08333333 0.08333333
  Marked 0.08333333 0.25000000
  1. addmargins()
    교차표에 행과 열의 빈도합을 포함
    addmargins(교차표, margin = 1 or 2)
> addmargins(crosstab, margin=1)  # 행 값을 모두 합한 합계행
         Placebo Treated
  None        29      13
  Some         7       7
  Marked       7      21
  Sum         43      41

> addmargins(crosstab, margin=2)  # 열 값을 모두 합한 합계열        
         Placebo Treated Sum
  None        29      13  42
  Some         7       7  14
  Marked       7      21  28

> addmargins(crosstab)  # margin 인수 지정하지 않으면, 두 변수 모두에 대한 합계      
         Placebo Treated Sum
  None        29      13  42
  Some         7       7  14
  Marked       7      21  28
  Sum         43      41  84
> addmargins(prop.table(crosstab, margin=2))  # 열의 합이 1이라는 교차표 명시
        
           Placebo   Treated       Sum
  None   0.6744186 0.3170732 0.9914918
  Some   0.1627907 0.1707317 0.3335224
  Marked 0.1627907 0.5121951 0.6749858
  Sum    1.0000000 1.0000000 2.0000000
> addmargins(prop.table(crosstab, margin=1))  # 행의 합이 1이라는 교차표 명시시
        
           Placebo   Treated       Sum
  None   0.6904762 0.3095238 1.0000000
  Some   0.5000000 0.5000000 1.0000000
  Marked 0.2500000 0.7500000 1.0000000
  Sum    1.4404762 1.5595238 3.0000000
  1. CrossTable()
    좀 더 많은 정보를 포함하고 있는 교차표
    gmodels 패키지 CrossTable(행, 열) 함수
> install.packages("gmodels")
> library(gmodels)

> CrossTable(Arthritis$Improved, Arthritis$Treatment, prop.chisq=FALSE, dnn=c("Inproved", "Treatment"))
  Cell Contents
|-------------------------|
|                       N |
|           N / Row Total |
|           N / Col Total |
|         N / Table Total |
|-------------------------|

 
Total Observations in Table:  84 

 
             | Treatment 
    Inproved |   Placebo |   Treated | Row Total | 
-------------|-----------|-----------|-----------|
        None |        29 |        13 |        42 | 
             |     0.690 |     0.310 |     0.500 | 
             |     0.674 |     0.317 |           | 
             |     0.345 |     0.155 |           | 
-------------|-----------|-----------|-----------|
        Some |         7 |         7 |        14 | 
             |     0.500 |     0.500 |     0.167 | 
             |     0.163 |     0.171 |           | 
             |     0.083 |     0.083 |           | 
-------------|-----------|-----------|-----------|
      Marked |         7 |        21 |        28 | 
             |     0.250 |     0.750 |     0.333 | 
             |     0.163 |     0.512 |           | 
             |     0.083 |     0.250 |           | 
-------------|-----------|-----------|-----------|
Column Total |        43 |        41 |        84 | 
             |     0.512 |     0.488 |           | 
-------------|-----------|-----------|-----------|

📌 다차원 테이블

  1. table()
> multtab <- table(Arthritis$Improved, Arthritis$Sex, Arthritis$Treatment)
> multtab
, ,  = Placebo

        
         Female Male
  None       19   10
  Some        7    0
  Marked      6    1

, ,  = Treated

        
         Female Male
  None        6    7
  Some        5    2
  Marked     16    5
  1. xtabs()
> multtab2 <- xtabs(~ Improved + Sex + Treatment, data=Arthritis)
> multtab2
, , Treatment = Placebo

        Sex
Improved Female Male
  None       19   10
  Some        7    0
  Marked      6    1

, , Treatment = Treated

        Sex
Improved Female Male
  None        6    7
  Some        5    2
  Marked     16    5
  1. ftable()
    다차원 테이블을 ftable() 함수 이용하면 더 단순하고 보기 좋게 출력 가능
> ftable(multtab)
               Placebo Treated
                              
None   Female       19       6
       Male         10       7
Some   Female        7       5
       Male          0       2
Marked Female        6      16
       Male          1       5

> ftable(multtab, row.vars=c(2, 3))  # c(2, 3) 차원을 행에 배치, 2번째 변수 Sex, 3번째 변수 Treatment
                None Some Marked
                                
Female Placebo    19    7      6
       Treated     6    5     16
Male   Placebo    10    0      1
       Treated     7    2      5
> # ftable()은 dataframe으로부터 직접 테이블 생성 가능 (위와 같은 결과)

> ftable(Arthritis[c("Improved", "Sex", "Treatment")], row.vars=c(2, 3))
                 Improved None Some Marked
Sex    Treatment                          
Female Placebo              19    7      6
       Treated               6    5     16
Male   Placebo              10    0      1
       Treated               7    2      5

💻 위 내용들을 이용한 여러가지 예제

> margin.table(multtab2, 1)  # 첫 번째 차원에 대해 빈도합
Improved
  None   Some Marked 
    42     14     28 
> margin.table(multtab2, 2)  # 두 번째 차원에 대해 빈도합
Sex
Female   Male 
    59     25 
> margin.table(multtab2, 3)  # 세 번째 차원에 대해 빈도합합
Treatment
Placebo Treated 
     43      41 
> # margin 인수에는 복수 차원도 가능
> margin.table(multtab2, c(1, 3))
        Treatment
Improved Placebo Treated
  None        29      13
  Some         7       7
  Marked       7      21
> # 복수 차원을 인수로 지정하게 되면 변수들 간의 관계를 보여주는 교차표 생성 가능
> # 성별과 치료제의 조합에 따라 치료효과에 차이가 있는지를 보여주는 교차표

> ftable(prop.table(multtab2, c(2, 3)))
                Treatment    Placebo    Treated
Improved Sex                                   
None     Female           0.59375000 0.22222222
         Male             0.90909091 0.50000000
Some     Female           0.21875000 0.18518519
         Male             0.00000000 0.14285714
Marked   Female           0.18750000 0.59259259
         Male             0.09090909 0.35714286

> ftable(addmargins(prop.table(multtab2, c(2, 3)), 1))
                Treatment    Placebo    Treated
Improved Sex                                   
None     Female           0.59375000 0.22222222
         Male             0.90909091 0.50000000
Some     Female           0.21875000 0.18518519
         Male             0.00000000 0.14285714
Marked   Female           0.18750000 0.59259259
         Male             0.09090909 0.35714286
Sum      Female           1.00000000 1.00000000
         Male             1.00000000 1.00000000

0개의 댓글