요인 수준 정리 (여러 수준 / 라벨 축소)
축소해야하는 여러 수준을 포함하는 요인을 정리하는 가장 효과적인 (즉, 효율적 / 적절한) 방법은 무엇입니까? 즉, 두 개 이상의 요인 수준을 하나로 결합하는 방법입니다.
다음은 두 수준 "예"와 "Y"를 "예"로 축소하고 "아니요"와 "N"을 "아니요"로 축소 한 예입니다.
## Given:
x <- c("Y", "Y", "Yes", "N", "No", "H") # The 'H' should be treated as NA
## expectedOutput
[1] Yes Yes Yes No No <NA>
Levels: Yes No # <~~ NOTICE ONLY **TWO** LEVELS
한 가지 옵션은 물론 손으로 사용하기 전에 현을 청소하는 것 sub
입니다.
또 다른 방법은 중복 라벨을 허용 한 다음 삭제하는 것입니다.
## Duplicate levels ==> "Warning: deprecated"
x.f <- factor(x, levels=c("Y", "Yes", "No", "N"), labels=c("Yes", "Yes", "No", "No"))
## the above line can be wrapped in either of the next two lines
factor(x.f)
droplevels(x.f)
그러나 더 효과적인 방법이 있습니까?
levels
및 labels
인수가 벡터 여야 한다는 것을 알고 있지만 , 목록과 명명 된 목록 및 명명 된 벡터를 실험하여 무슨 일이 일어나는지 확인했습니다. 말할 필요도없이 다음 중 어느 것도 내 목표에 더 가까워지지 않았습니다.
factor(x, levels=list(c("Yes", "Y"), c("No", "N")), labels=c("Yes", "No"))
factor(x, levels=c("Yes", "No"), labels=list(c("Yes", "Y"), c("No", "N")))
factor(x, levels=c("Y", "Yes", "No", "N"), labels=c(Y="Yes", Yes="Yes", No="No", N="No"))
factor(x, levels=c("Y", "Yes", "No", "N"), labels=c(Yes="Y", Yes="Yes", No="No", No="N"))
factor(x, levels=c("Yes", "No"), labels=c(Y="Yes", Yes="Yes", No="No", N="No"))
업데이트 2 : 빠르게 표준이되고있는 새로운 "tidyverse"방식을 보여주는 Uwe의 답변을 참조하십시오.
업데이트 1 : 중복 된 레이블 (레벨은 아님)이 이제 실제로 허용됩니다 (위의 의견에 따라). Tim의 대답을 참조하십시오.
원래 답변, 그러나 여전히 유용하고 흥미 롭습니다 levels
. 정확히이 목적을 위해 명명 된 목록을 함수 에 전달하는 알려진 옵션이 거의 없습니다 . 목록의 이름은 원하는 레벨 이름이어야하며 요소는 이름을 바꿔야하는 현재 이름이어야합니다. 일부 (OP 포함, Tim의 답변에 대한 Ricardo의 의견 참조)는 읽기 쉽도록 이것을 선호합니다.
x <- c("Y", "Y", "Yes", "N", "No", "H", NA)
x <- factor(x)
levels(x) <- list("Yes"=c("Y", "Yes"), "No"=c("N", "No"))
x
## [1] Yes Yes Yes No No <NA> <NA>
## Levels: Yes No
levels
문서 에서 언급했듯이 ; 또한 거기에있는 예를 참조하십시오.
value : 'factor'방법의 경우 길이가 'x'레벨 수 이상인 문자열 벡터 또는 레벨 이름을 바꾸는 방법을 지정하는 명명 된 목록입니다.
Marek이 여기에서 한 것처럼 한 줄로도이 작업을 수행 할 수 있습니다. https://stackoverflow.com/a/10432263/210673 ; levels<-
마법은 여기에 설명 https://stackoverflow.com/a/10491881/210673 .
> `levels<-`(factor(x), list(Yes=c("Y", "Yes"), No=c("N", "No")))
[1] Yes Yes Yes No No <NA>
Levels: Yes No
질문의 제목이 요인 수준 정리 (여러 수준 / 레이블 축소) 이므로 forcats
완전성을 위해 여기에서도 패키지를 언급해야합니다. forcats
2016 년 8 월 CRAN에 등장했습니다.
요인 수준을 정리하는 데 사용할 수있는 몇 가지 편의 기능이 있습니다.
x <- c("Y", "Y", "Yes", "N", "No", "H")
library(forcats)
요인 수준을 수동으로 정의 된 그룹으로 축소
fct_collapse(x, Yes = c("Y", "Yes"), No = c("N", "No"), NULL = "H")
#[1] Yes Yes Yes No No <NA>
#Levels: No Yes
수동으로 요인 수준 변경
fct_recode(x, Yes = "Y", Yes = "Yes", No = "N", No = "No", NULL = "H")
#[1] Yes Yes Yes No No <NA>
#Levels: No Yes
요인 수준의 레이블을 자동으로 다시 지정하고 필요에 따라 축소
fun <- function(z) {
z[z == "Y"] <- "Yes"
z[z == "N"] <- "No"
z[!(z %in% c("Yes", "No"))] <- NA
z
}
fct_relabel(factor(x), fun)
#[1] Yes Yes Yes No No <NA>
#Levels: No Yes
참고 fct_relabel()
그것은 기대 때문에, 요소 수준에서 작동 요소 첫 번째 인수로합니다. 두 가지 다른 기능, fct_collapse()
그리고 fct_recode()
, 또한 동의를 문자 벡터 문서화되지 않은 기능입니다.
첫 출현으로 요인 수준 재정렬
OP가 제공하는 예상 출력은 다음과 같습니다.
[1] Yes Yes Yes No No <NA>
Levels: Yes No
여기에서는 x
기본값과 다른 수준으로 표시되는 순서가 지정됩니다 ( ?factor
: 요인 수준은 기본적으로 정렬 됨 ).
예상되는 출력에 맞추려면 레벨을 축소 fct_inorder()
하기 전에 다음 을 사용하여 수행 할 수 있습니다 .
fct_collapse(fct_inorder(x), Yes = c("Y", "Yes"), No = c("N", "No"), NULL = "H")
fct_recode(fct_inorder(x), Yes = "Y", Yes = "Yes", No = "N", No = "No", NULL = "H")
둘 다 동일한 순서로 레벨이있는 예상 출력을 지금 반환합니다.
아마도 명명 된 벡터를 키로 사용할 수 있습니다.
> factor(unname(c(Y = "Yes", Yes = "Yes", N = "No", No = "No", H = NA)[x]))
[1] Yes Yes Yes No No <NA>
Levels: No Yes
이것은 당신의 마지막 시도와 매우 유사 해 보입니다 ...하지만 이것은 작동합니다 :-)
또 다른 방법은 매핑을 포함하는 테이블을 만드는 것입니다.
# stacking the list from Aaron's answer
fmap = stack(list(Yes = c("Y", "Yes"), No = c("N", "No")))
fmap$ind[ match(x, fmap$values) ]
# [1] Yes Yes Yes No No <NA>
# Levels: No Yes
# or...
library(data.table)
setDT(fmap)[x, on=.(values), ind ]
# [1] Yes Yes Yes No No <NA>
# Levels: No Yes
나는지도를 요약하는 쉽게 검사 할 수있는 객체를 남기기 때문에 이런 방식을 선호합니다. data.table 코드는 해당 구문의 다른 조인처럼 보입니다.
물론 fmap
변경 사항을 요약하는 것과 같은 객체를 원하지 않는 경우 "한 줄"이 될 수 있습니다.
library(data.table)
setDT(stack(list(Yes = c("Y", "Yes"), No = c("N", "No"))))[x, on=.(values), ind ]
# [1] Yes Yes Yes No No <NA>
# Levels: No Yes
이 답변을 추가하여 데이터 프레임의 특정 요소에서 작동하는 허용 된 답변을 보여줍니다. 처음에는 분명하지 않았기 때문입니다 (아마도 그랬어 야했지만).
levels(df$var1)
# "0" "1" "Z"
summary(df$var1)
# 0 1 Z
# 7012 2507 8
levels(df$var1) <- list("0"=c("Z", "0"), "1"=c("1"))
levels(df$var1)
# "0" "1"
summary(df$var1)
# 0 1
# 7020 2507
R 3.5.0 (2018-04-23)부터 명확하고 간단한 한 줄로이를 수행 할 수 있습니다.
x = c("Y", "Y", "Yes", "N", "No", "H") # The 'H' should be treated as NA
tmp = factor(x, levels= c("Y", "Yes", "N", "No"), labels= c("Yes", "Yes", "No", "No"))
tmp
# [1] Yes Yes Yes No No <NA>
# Levels: Yes No
한 줄, 여러 값을 동일한 수준에 매핑하고 누락 된 수준에 대해 NA를 설정합니다. "– h / t @Aaron
나는 당신의 실제 사용 사례를 모르지만 strtrim
여기서는 아무 쓸모가 없을 것입니다 ...
factor( strtrim( x , 1 ) , levels = c("Y" , "N" ) , labels = c("Yes" , "No" ) )
#[1] Yes Yes Yes No No <NA>
#Levels: Yes No
@Aaron의 접근 방식과 비슷하지만 약간 더 간단합니다.
x <- c("Y", "Y", "Yes", "N", "No", "H")
x <- factor(x)
# levels(x)
# [1] "H" "N" "No" "Y" "Yes"
# NB: the offending levels are 1, 2, & 4
levels(x)[c(1,2,4)] <- c(NA, "No", "Yes")
x
# [1] Yes Yes Yes No No <NA>
# Levels: No Yes
You may use the below function for combining/collapsing multiple factors:
combofactor <- function(pattern_vector,
replacement_vector,
data) {
levels <- levels(data)
for (i in 1:length(pattern_vector))
levels[which(pattern_vector[i] == levels)] <-
replacement_vector[i]
levels(data) <- levels
data
}
Example:
Initialize x
x <- factor(c(rep("Y",20),rep("N",20),rep("y",20),
rep("yes",20),rep("Yes",20),rep("No",20)))
Check the structure
str(x)
# Factor w/ 6 levels "N","No","y","Y",..: 4 4 4 4 4 4 4 4 4 4 ...
Use the function:
x_new <- combofactor(c("Y","N","y","yes"),c("Yes","No","Yes","Yes"),x)
Recheck the structure:
str(x_new)
# Factor w/ 2 levels "No","Yes": 2 2 2 2 2 2 2 2 2 2 ...
First let's note that in this specific case we can use partial matching:
x <- c("Y", "Y", "Yes", "N", "No", "H")
y <- c("Yes","No")
x <- factor(y[pmatch(x,y,duplicates.ok = TRUE)])
# [1] Yes Yes Yes No No <NA>
# Levels: No Yes
In a more general case I'd go with dplyr::recode
:
library(dplyr)
x <- c("Y", "Y", "Yes", "N", "No", "H")
y <- c(Y="Yes",N="No")
x <- recode(x,!!!y)
x <- factor(x,y)
# [1] Yes Yes Yes No No <NA>
# Levels: Yes No
Slightly altered if the starting point is a factor:
x <- factor(c("Y", "Y", "Yes", "N", "No", "H"))
y <- c(Y="Yes",N="No")
x <- recode_factor(x,!!!y)
x <- factor(x,y)
# [1] Yes Yes Yes No No <NA>
# Levels: Yes No
ReferenceURL : https://stackoverflow.com/questions/19410108/cleaning-up-factor-levels-collapsing-multiple-levels-labels
'programing' 카테고리의 다른 글
LLDB가 view.bounds를 인쇄 할 수없는 이유는 무엇입니까? (0) | 2021.01.18 |
---|---|
16 진수 문자열에 대한 바이트 배열 (0) | 2021.01.18 |
응용 프로그램을 다시 시작하지 않고 동적으로 로그 수준 변경 (0) | 2021.01.18 |
UICollectionView 단일 셀 업데이트 (0) | 2021.01.18 |
Eclipse에서 클래스 경로에 파일을 배치하는 방법은 무엇입니까? (0) | 2021.01.17 |