R factor 변환 - R factor byeonhwan

요인은 정수로 저장되고, 유일무이한 정수와 연관된 표식을 갖는다. 요인은 문자벡터처럼 보이지만(흔히 행동한다), 실제로 내부를 보면 정수다. 문자열처럼 요인을 다룰 때, 주의를 기울일 필요가 있다.

요인이 생성되면, 요인은 수준(level)으로 알려진 사전에 정의된 집합값만 담을 수 있다. 기본 디폴트 설정으로, R은 항상 수준을 알파벳 순으로 정렬한다. 예를 들어, 만약 수준 2을 갖는 요인이 있다면:

조언

nlevels(sex)
3 명령어를 사용해서 R에 요인을 생성하고 변경한다.

sex <- factor(c("male", "female", "female", "male"))

R은

nlevels(sex)
4을
nlevels(sex)
5 수준에,
nlevels(sex)
6를
nlevels(sex)
7 수준에 할당한다. 왜냐하면
nlevels(sex)
8가
nlevels(sex)
9보다 앞서기 때문이다.
[1] 2
0 함수를 사용해서 이점을 확인할 수 있다.
[1] 2
1 함수를 사용해서 수준의 갯수도 확인할 수 있다:

levels(sex)

[1] "female" "male"  

nlevels(sex)

[1] 2

때때로, 요인 순위가 문제가 되지 않지만, 다른 때는 순위를 명세하는 것이 필요한데, 이유는 순위가 유의미(예를 들어, “low”, “medium”, “high”)하기 때문이다. 혹은 특정 유형의 자료분석에서 필요하기 때문이다. 부가적으로, 수준에 대한 순위를 명세하면 수준을 비교할 수 있게 된다:

food <- factor(c("low", "high", "medium", "high", "low", "medium", "high"))
levels(food)

[1] "high"   "low"    "medium"

food <- factor(food, levels=c("low", "medium", "high"))
levels(food)

[1] "low"    "medium" "high"  

min(food) ## 돌아가지 않는다.

levels(sex)
0

levels(sex)
1

[1] "low"    "medium" "high"  

levels(sex)
3

levels(sex)
4

R 메모리에서, 상기 요인은 숫자 (1, 2, 3)으로 표현된다. 간단한 정수 표식을 사용하는 것보다 요인을 사용하는 것이 더 낫다. 왜냐하면 요인은 자기 기술을 하기 때문이다:

[1] 2
2,
[1] 2
3,
[1] 2
4“와 같은 표기법이
nlevels(sex)
4,
nlevels(sex)
6,
[1] 2
7 보다 더 기술을 잘하고 있다.”low“는 어떤 것인가? 정수형 데이터로는 분간할 수 없다. 요인은 이러한 정보가 붙박이로 내장되어 있다. (예제 데이터셋에 나온 피험자처럼) 특히 수준이 많은 경우 도움이 된다.

레벨의 순서 변경보다 값을 변경하는 게 더 강력한 방법이다. 이렇게 하면 화면 출력 시 라벨을 명확히 할 수 있고, 레벨을 병합하여 상위 레벨 시각화를 할 수 있다. 가장 일반적이고 강력한 것은 fct_recode() 이다. 이를 사용하여 각 레벨값을 다시 주거나 변경할 수 있다. 예를 들어 gss_cat$partyid 를 보자.

gss_cat %>% count(partyid)
#> # A tibble: 10 × 2
#>   partyid                n
#>                 
#> 1 No answer            154
#> 2 Don't know             1
#> 3 Other party          393
#> 4 Strong republican   2314
#> 5 Not str republican  3032
#> 6 Ind,near rep        1791
#> # … with 4 more rows

이 레벨들은 짧고 일관성이 없다. 이 레벨들을 풀어쓰고, 병렬 구조를 사용해보자.

gss_cat %>%
  mutate(partyid = fct_recode(partyid,
    "Republican, strong"    = "Strong republican",
    "Republican, weak"      = "Not str republican",
    "Independent, near rep" = "Ind,near rep",
    "Independent, near dem" = "Ind,near dem",
    "Democrat, weak"        = "Not str democrat",
    "Democrat, strong"      = "Strong democrat"
  )) %>%
  count(partyid)
#> # A tibble: 10 × 2
#>   partyid                   n
#>                    
#> 1 No answer               154
#> 2 Don't know                1
#> 3 Other party             393
#> 4 Republican, strong     2314
#> 5 Republican, weak       3032
#> 6 Independent, near rep  1791
#> # … with 4 more rows

fct_recode() 는 명시적으로 언급되지 않은 레벨은 그대로 둔다. 존재하지 않은 레벨을 참조하면 경고를 발생한다.

그룹을 결합하려면 이전 레벨들을 같은 새로운 레벨로 할당하면 된다.

gss_cat %>%
  mutate(partyid = fct_recode(partyid,
    "Republican, strong"    = "Strong republican",
    "Republican, weak"      = "Not str republican",
    "Independent, near rep" = "Ind,near rep",
    "Independent, near dem" = "Ind,near dem",
    "Democrat, weak"        = "Not str democrat",
    "Democrat, strong"      = "Strong democrat",
    "Other"                 = "No answer",
    "Other"                 = "Don't know",
    "Other"                 = "Other party"
  )) %>%
  count(partyid)
#> # A tibble: 8 × 2
#>   partyid                   n
#>                    
#> 1 Other                   548
#> 2 Republican, strong     2314
#> 3 Republican, weak       3032
#> 4 Independent, near rep  1791
#> 5 Independent            4119
#> 6 Independent, near dem  2499
#> # … with 2 more rows

이 기술은 신중하게 사용해야 한다. 서로 같지 않은 범주들을 함께 묶는다면 잘못된 결과를 도출하게 될 것이다.

다수의 레벨을 병합하고자 하면 fct_recode() 의 변형 함수인

gss_cat %>%
  mutate(partyid = fct_recode(partyid,
    "Republican, strong"    = "Strong republican",
    "Republican, weak"      = "Not str republican",
    "Independent, near rep" = "Ind,near rep",
    "Independent, near dem" = "Ind,near dem",
    "Democrat, weak"        = "Not str democrat",
    "Democrat, strong"      = "Strong democrat"
  )) %>%
  count(partyid)
#> # A tibble: 10 × 2
#>   partyid                   n
#>                    
#> 1 No answer               154
#> 2 Don't know                1
#> 3 Other party             393
#> 4 Republican, strong     2314
#> 5 Republican, weak       3032
#> 6 Independent, near rep  1791
#> # … with 4 more rows
0 가 편리하다. 각각의 새로운 변수에 대해 이전 레벨로 이루어진 벡터를 제공해야 한다.

gss_cat %>%
  mutate(partyid = fct_collapse(partyid,
    other = c("No answer", "Don't know", "Other party"),
    rep = c("Strong republican", "Not str republican"),
    ind = c("Ind,near rep", "Independent", "Ind,near dem"),
    dem = c("Not str democrat", "Strong democrat")
  )) %>%
  count(partyid)
#> # A tibble: 4 × 2
#>   partyid     n
#>      
#> 1 other     548
#> 2 rep      5346
#> 3 ind      8409
#> 4 dem      7180

가끔은 플롯이나 테이블을 간단하게 만들기 위해 소규모 그룹 모두를 묶고 싶을 수도 있다.

gss_cat %>%
  mutate(partyid = fct_recode(partyid,
    "Republican, strong"    = "Strong republican",
    "Republican, weak"      = "Not str republican",
    "Independent, near rep" = "Ind,near rep",
    "Independent, near dem" = "Ind,near dem",
    "Democrat, weak"        = "Not str democrat",
    "Democrat, strong"      = "Strong democrat"
  )) %>%
  count(partyid)
#> # A tibble: 10 × 2
#>   partyid                   n
#>                    
#> 1 No answer               154
#> 2 Don't know                1
#> 3 Other party             393
#> 4 Republican, strong     2314
#> 5 Republican, weak       3032
#> 6 Independent, near rep  1791
#> # … with 4 more rows
1 가 바로 이 작업을 한다.

gss_cat %>%
  mutate(relig = fct_lump(relig)) %>%
  count(relig)
#> # A tibble: 2 × 2
#>   relig          n
#>         
#> 1 Protestant 10846
#> 2 Other      10637

기본 동작은 묶은 그룹이 가장 작은 그룹이 되는 조건을 유지하면서 작은 그룹들을 점진적으로 묶는다. 위의 경우에는 매우 도움이 되지는 않는다. 즉, 이 조사에서 대부분의 미국인이 개신교인 것은 사실이지만, 아마도 우리는 과하게 병합한 것 같다.