값 순서를 변경하지 않고 요인 수준 재정렬
수치 변수와 범주형 데이터 프레임이 있습니다.factor변수그 요인들의 수준 순서는 제가 원하는 방식이 아닙니다.
numbers <- 1:4
letters <- factor(c("a", "b", "c", "d"))
df <- data.frame(numbers, letters)
df
# numbers letters
# 1 1 a
# 2 2 b
# 3 3 c
# 4 4 d
수준의 순서를 변경하면 문자가 해당 숫자와 더 이상 일치하지 않습니다(이 시점부터 내 데이터는 완전히 무의미합니다).
levels(df$letters) <- c("d", "c", "b", "a")
df
# numbers letters
# 1 1 d
# 2 2 c
# 3 3 b
# 4 4 a
레벨 순서를 변경하기만 하면 되므로 플롯할 때 막대가 원하는 순서로 표시됩니다. 이 순서는 기본 알파벳 순서와 다를 수 있습니다.
사용levels의 주장.factor:
df <- data.frame(f = 1:4, g = letters[1:4])
df
# f g
# 1 1 a
# 2 2 b
# 3 3 c
# 4 4 d
levels(df$g)
# [1] "a" "b" "c" "d"
df$g <- factor(df$g, levels = letters[4:1])
# levels(df$g)
# [1] "d" "c" "b" "a"
df
# f g
# 1 1 a
# 2 2 b
# 3 3 c
# 4 4 d
좀 더, 참고로.
## reorder is a base function
df$letters <- reorder(df$letters, new.order=letters[4:1])
library(gdata)
df$letters <- reorder.factor(df$letters, letters[4:1])
유용한 Relevel 및 combine_factor도 찾을 수 있습니다.
이 질문이 마지막으로 활성화된 이후로 해들리는 그의 새로운 질문을 발표했습니다.forcats요인을 조작하기 위한 패키지인데 엄청나게 유용하다는 걸 알게 되었습니다.OP의 데이터 프레임의 예:
levels(df$letters)
# [1] "a" "b" "c" "d"
수준을 되돌리는 방법:
library(forcats)
fct_rev(df$letters) %>% levels
# [1] "d" "c" "b" "a"
수준을 추가하려면:
fct_expand(df$letters, "e") %>% levels
# [1] "a" "b" "c" "d" "e"
그리고 더 유용한 것은fct_xxx()기능들.
따라서 어휘집에서 원하는 것은 주어진 요인 변수에 대한 레이블만 변경하는 것입니다(즉, 요인 수준뿐만 아니라 데이터도 변경하지 않고 그대로 유지).
df$letters = factor(df$letters, labels=c("d", "c", "b", "a"))
데이터 또는 요인 스키마(데이터 점이 개별 빈 또는 요인 값으로 결합되는 방식)가 아닌 데이터 점 대 레이블 매핑만 변경하려는 경우, 처음 요인을 생성할 때 매핑이 원래 어떻게 설정되는지 아는 데 도움이 될 수 있습니다.
규칙은 간단합니다.
- 레이블은 인덱스 값을 기준으로 레벨에 매핑됩니다(즉, 레벨 [2]의 값에 레이블 [2]가 지정됨).
- 요인 수준은 levels 인수를 통해 전달하여 명시적으로 설정할 수 있습니다.
- levels 인수에 대해 값이 제공되지 않으면 (데이터 인수에 대해) 전달된 데이터 벡터에서 고유한 결과 호출인 기본값이 사용됩니다.
- 라벨 인수를 통해 라벨을 명시적으로 설정할 수 있습니다.
- labels 인수에 대한 값이 제공되지 않으면 레벨 벡터에 해당하는 기본값이 사용됩니다.
R의 요소들을 다루는 것은 꽤 특이한 일입니다, 인정해야겠습니다...요인 수준을 재정렬하는 동안 기본 숫자 값을 재정렬하지 않습니다.여기 작은 시연이 있습니다.
> numbers = 1:4
> letters = factor(letters[1:4])
> dtf <- data.frame(numbers, letters)
> dtf
numbers letters
1 1 a
2 2 b
3 3 c
4 4 d
> sapply(dtf, class)
numbers letters
"integer" "factor"
이제 이 요인을 숫자로 변환하면 다음을 얻을 수 있습니다.
# return underlying numerical values
1> with(dtf, as.numeric(letters))
[1] 1 2 3 4
# change levels
1> levels(dtf$letters) <- letters[4:1]
1> dtf
numbers letters
1 1 d
2 2 c
3 3 b
4 4 a
# return numerical values once again
1> with(dtf, as.numeric(letters))
[1] 1 2 3 4
가 아니라레벨을 변경함으로써 레벨만 변경할 수 있습니다(누가 알겠습니까, 네?). 수치는 변경할 수 없습니다!하지만, 당신이 사용할 때.factor@Jonathan Chang이 제안한 것처럼, 어떤 다른 일이 일어납니다: 당신은 수치 그 자체를 변경합니다.
. 은 ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠlevels그리고 나서 그것을 풀어내려고 노력합니다.factor하지 마!!!사용 안 함levels그렇지 않으면 (자신이 무엇을 하고 있는지 정확히 알지 못하는 한) 일을 망칠 것입니다.
lil'을 지정하는 것을 (One lil' 제: R의객동이객이일지마름름십오시정지하을안체로의으한와체▁oneone마▁r오▁suggest시▁naming십:ion▁your▁avoid'▁with▁objects▁(지지'▁as정▁lil'하▁objects▁an▁lil▁r제).df는 F, F 분포에 함니다입수밀도입니다.letters는 소문자 알파벳 문자를 제공합니다.이 경우 코드에 결함이 없을 수도 있지만 가끔은...하지만 이것은 혼란을 일으킬 수 있고, 우리는 그것을 원하지 않습니다, 그렇죠?!?=)
대신 다음과 같은 것을 사용합니다(처음부터 다시 한 번 말씀드리겠습니다).
> dtf <- data.frame(f = 1:4, g = factor(letters[1:4]))
> dtf
f g
1 1 a
2 2 b
3 3 c
4 4 d
> with(dtf, as.numeric(g))
[1] 1 2 3 4
> dtf$g <- factor(dtf$g, levels = letters[4:1])
> dtf
f g
1 1 a
2 2 b
3 3 c
4 4 d
> with(dtf, as.numeric(g))
[1] 4 3 2 1
이름을 지정할 수도 있습니다.data.frame와 함께df그리고.letters에 g결과는 괜찮을 것입니다.사실 이 코드는 당신이 올린 코드와 동일하고 이름만 바뀌었습니다. 파트 이분부.factor(dtf$letter, levels = letters[4:1])오류를 던지지는 않겠지만, 혼란스러울 수 있습니다!
읽어기를 .?factor철저한 매뉴얼!사이에 무슨 차이가 있습니까?factor(g, levels = letters[4:1])그리고.factor(g, labels = letters[4:1])에서유점에서 비슷한 levels(g) <- letters[4:1]그리고.g <- factor(g, labels = letters[4:1])?
ggplot 구문을 입력하면 더 많은 도움을 드릴 수 있습니다!
건배!!!
편집:
ggplot2실제로 레벨과 값을 모두 변경해야 합니까?가 이걸요, 제가... 제가 이걸 파낼게요...
아래 예시와 같이 레벨이 숫자를 포함하는 문자열일 수 있는 다른 경우를 추가하고 싶습니다.
df <- data.frame(x = c("15-25", "0-4", "5-10", "11-14", "100+"))
은 " " " 입니다.x다음과 같습니다.
df$x
# [1] 15-25 0-4 5-10 11-14 100+
# Levels: 0-4 100+ 11-14 15-25 5-10
여기서 수준을 명시적으로 작성하지 않고 숫자 값에 따라 요인 수준을 다시 정렬하려면 다음과 같이 할 수 있습니다.
library(gtools)
df$x <- factor(df$x, levels = mixedsort(df$x))
df$x
# [1] 15-25 0-4 5-10 11-14 100+
# Levels: 0-4 5-10 11-14 15-25 100+
as.numeric(df$x)
# [1] 4 1 2 3 5
이것이 미래의 독자들에게 유용한 정보로 여겨질 수 있기를 바랍니다.
다음은 주어진 데이터 프레임의 요인을 재정렬하는 기능입니다.
reorderFactors <- function(df, column = "my_column_name",
desired_level_order = c("fac1", "fac2", "fac3")) {
x = df[[column]]
lvls_src = levels(x)
idxs_target <- vector(mode="numeric", length=0)
for (target in desired_level_order) {
idxs_target <- c(idxs_target, which(lvls_src == target))
}
x_new <- factor(x,levels(x)[idxs_target])
df[[column]] <- x_new
return (df)
}
용도:reorderFactors(df, "my_col", desired_level_order = c("how","I","want"))
저는 단순히 levels 인수를 사용할 것입니다.
levels(df$letters) <- levels(df$letters)[c(4:1)]
다른 s 패키지의 함수를 기억하는 것에서 해방되어 매우 유용한 다른 접근법을 추가하는 것입니다.요인의 수준은 속성에 불과하므로 다음 작업을 수행할 수 있습니다.
numbers <- 1:4
letters <- factor(c("a", "b", "c", "d"))
df <- data.frame(numbers, letters)
# Original attributes
> attributes(df$letters)
$levels
[1] "a" "b" "c" "d"
$class
[1] "factor"
# Modify attributes
attr(df$letters,"levels") <- c("d", "c", "b", "a")
> df$letters
[1] d c b a
Levels: d c b a
# New attributes
> attributes(df$letters)
$levels
[1] "d" "c" "b" "a"
$class
[1] "factor"
언급URL : https://stackoverflow.com/questions/2375587/reorder-levels-of-a-factor-without-changing-order-of-values
'programing' 카테고리의 다른 글
| Python을 사용하여 csv 파일을 처리할 때 헤더를 건너뛰는 방법은 무엇입니까? (0) | 2023.06.18 |
|---|---|
| 구문 오류:예기치 않은 토큰 가져오기 TypeORM 엔티티 (0) | 2023.06.18 |
| 이름의 목적은 무엇입니까? (0) | 2023.06.13 |
| 전체 구성 요소를 사용자에게 설치하지 않고 ODAC를 사용하는 .NET 응용 프로그램을 배포하려면 어떻게 해야 합니까? (0) | 2023.06.13 |
| 로그아웃할 때 블랙리스트에 대한 400건의 잘못된 요청을 받았습니다. (0) | 2023.06.13 |