정보 손실 없이 인자를 정수\숫자로 변환하는 방법은 무엇입니까?
요인을 숫자 또는 정수로 변환하면 값이 숫자가 아닌 기본 수준 코드를 얻습니다.
f <- factor(sample(runif(5), 20, replace = TRUE))
## [1] 0.0248644019011408 0.0248644019011408 0.179684827337041
## [4] 0.0284090070053935 0.363644931698218 0.363644931698218
## [7] 0.179684827337041 0.249704354675487 0.249704354675487
## [10] 0.0248644019011408 0.249704354675487 0.0284090070053935
## [13] 0.179684827337041 0.0248644019011408 0.179684827337041
## [16] 0.363644931698218 0.249704354675487 0.363644931698218
## [19] 0.179684827337041 0.0284090070053935
## 5 Levels: 0.0248644019011408 0.0284090070053935 ... 0.363644931698218
as.numeric(f)
## [1] 1 1 3 2 5 5 3 4 4 1 4 2 3 1 3 5 4 5 3 2
as.integer(f)
## [1] 1 1 3 2 5 5 3 4 4 1 4 2 3 1 3 5 4 5 3 2
에 의지해야 합니다.paste
실제 값을 얻는 방법:
as.numeric(paste(f))
## [1] 0.02486440 0.02486440 0.17968483 0.02840901 0.36364493 0.36364493
## [7] 0.17968483 0.24970435 0.24970435 0.02486440 0.24970435 0.02840901
## [13] 0.17968483 0.02486440 0.17968483 0.36364493 0.24970435 0.36364493
## [19] 0.17968483 0.02840901
요인을 숫자로 변환하는 더 좋은 방법이 있습니까?
의 경고 섹션을 참조하십시오.
특히,
as.numeric
요인에 적용되는 것은 의미가 없으며 암묵적인 강제에 의해 발생할 수 있습니다.하는f
의 숫자 값인 대략원래숫자값으로,▁approxim로▁values▁to으값,▁numeric자,as.numeric(levels(f))[f]
되며 권되며보약효간율보다 더 입니다.as.numeric(as.character(f))
.
왜?as.numeric(levels(f))[f]
보다 as.numeric(as.character(f))
?
as.numeric(as.character(f))
으로 입니다.as.numeric(levels(f)[f])
그래서 당신은 숫자로 변환을 수행하고 있습니다.length(x)
위아가가 아닌 값nlevels(x)
레벨이 긴 .속도 차이는 레벨이 적은 긴 벡터에서 가장 두드러집니다.값이 대부분 고유하다면 속도에 큰 차이가 없을 것입니다.변환을 어떻게 하든 이 작업은 코드의 병목 현상이 될 가능성이 낮으므로 너무 걱정하지 마십시오.
약간의 타이밍
library(microbenchmark)
microbenchmark(
as.numeric(levels(f))[f],
as.numeric(levels(f)[f]),
as.numeric(as.character(f)),
paste0(x),
paste(x),
times = 1e5
)
## Unit: microseconds
## expr min lq mean median uq max neval
## as.numeric(levels(f))[f] 3.982 5.120 6.088624 5.405 5.974 1981.418 1e+05
## as.numeric(levels(f)[f]) 5.973 7.111 8.352032 7.396 8.250 4256.380 1e+05
## as.numeric(as.character(f)) 6.827 8.249 9.628264 8.534 9.671 1983.694 1e+05
## paste0(x) 7.964 9.387 11.026351 9.956 10.810 2911.257 1e+05
## paste(x) 7.965 9.387 11.127308 9.956 11.093 2419.458 1e+05
R에는 요인을 변환하기 위한 (문서화되지 않은) 여러 가지 편의 기능이 있습니다.
as.character.factor
as.data.frame.factor
as.Date.factor
as.list.factor
as.vector.factor
- ...
하지만 짜증나게도, 요인 -> 숫자 변환을 처리할 수 있는 것이 없습니다.Joshua Ulrich의 답변의 확장으로, 저는 당신 자신의 관용적인 기능의 정의로 이 누락을 극복할 것을 제안합니다.
as.double.factor <- function(x) {as.numeric(levels(x))[x]}
스크립트 시작 부분에 저장하거나 파일에 저장할 수 있습니다.
참고: 이 답변은 숫자 값 요인을 숫자로 변환하는 것이 아니라 범주형 요인을 해당 수준 숫자로 변환하는 것입니다.
이 게시물의 모든 답변은 결과를 생성하지 못했습니다. NA가 생성되고 있습니다.
y2<-factor(c("A","B","C","D","A"));
as.numeric(levels(y2))[y2]
[1] NA NA NA NA NA Warning message: NAs introduced by coercion
제게 효과가 있었던 건...
as.integer(y2)
# [1] 1 2 3 4 1
은 가장쉬방법사것용다입니는하은운것다니입▁the를 사용하는 것입니다.unfactor
인자 벡터 또는 데이터 프레임을 수용할 수 있는 패키지 varhandle의 함수:
unfactor(your_factor_variable)
이 예는 빠른 시작이 될 수 있습니다.
x <- rep(c("a", "b", "c"), 20)
y <- rep(c(1, 1, 0), 20)
class(x) # -> "character"
class(y) # -> "numeric"
x <- factor(x)
y <- factor(y)
class(x) # -> "factor"
class(y) # -> "factor"
library(varhandle)
x <- unfactor(x)
y <- unfactor(y)
class(x) # -> "character"
class(y) # -> "numeric"
데이터 프레임에서도 사용할 수 있습니다.를 들어, 를들어예,,iris
데이터 집합:
sapply(iris, class)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species "numeric" "numeric" "numeric" "numeric" "factor"
# load the package
library("varhandle")
# pass the iris to unfactor
tmp_iris <- unfactor(iris)
# check the classes of the columns
sapply(tmp_iris, class)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species "numeric" "numeric" "numeric" "numeric" "character"
# check if the last column is correctly converted
tmp_iris$Species
[1] "setosa" "setosa" "setosa" "setosa" "setosa" [6] "setosa" "setosa" "setosa" "setosa" "setosa" [11] "setosa" "setosa" "setosa" "setosa" "setosa" [16] "setosa" "setosa" "setosa" "setosa" "setosa" [21] "setosa" "setosa" "setosa" "setosa" "setosa" [26] "setosa" "setosa" "setosa" "setosa" "setosa" [31] "setosa" "setosa" "setosa" "setosa" "setosa" [36] "setosa" "setosa" "setosa" "setosa" "setosa" [41] "setosa" "setosa" "setosa" "setosa" "setosa" [46] "setosa" "setosa" "setosa" "setosa" "setosa" [51] "versicolor" "versicolor" "versicolor" "versicolor" "versicolor" [56] "versicolor" "versicolor" "versicolor" "versicolor" "versicolor" [61] "versicolor" "versicolor" "versicolor" "versicolor" "versicolor" [66] "versicolor" "versicolor" "versicolor" "versicolor" "versicolor" [71] "versicolor" "versicolor" "versicolor" "versicolor" "versicolor" [76] "versicolor" "versicolor" "versicolor" "versicolor" "versicolor" [81] "versicolor" "versicolor" "versicolor" "versicolor" "versicolor" [86] "versicolor" "versicolor" "versicolor" "versicolor" "versicolor" [91] "versicolor" "versicolor" "versicolor" "versicolor" "versicolor" [96] "versicolor" "versicolor" "versicolor" "versicolor" "versicolor" [101] "virginica" "virginica" "virginica" "virginica" "virginica" [106] "virginica" "virginica" "virginica" "virginica" "virginica" [111] "virginica" "virginica" "virginica" "virginica" "virginica" [116] "virginica" "virginica" "virginica" "virginica" "virginica" [121] "virginica" "virginica" "virginica" "virginica" "virginica" [126] "virginica" "virginica" "virginica" "virginica" "virginica" [131] "virginica" "virginica" "virginica" "virginica" "virginica" [136] "virginica" "virginica" "virginica" "virginica" "virginica" [141] "virginica" "virginica" "virginica" "virginica" "virginica" [146] "virginica" "virginica" "virginica" "virginica" "virginica"
요인 레이블이 원래 값과 일치하는 경우에만 가능합니다.예를 들어 설명하겠습니다.
데터가벡가정다니합고터라이▁vector다라고 가정합니다.x
:
x <- c(20, 10, 30, 20, 10, 40, 10, 40)
이제 레이블이 네 개인 요인을 생성합니다.
f <- factor(x, levels = c(10, 20, 30, 40), labels = c("A", "B", "C", "D"))
1)x
double, 유이이 다니입중형▁type▁doublef
정수 형식입니다.이것은 피할 수 없는 첫 번째 정보 손실입니다.요인은 항상 정수로 저장됩니다.
> typeof(x)
[1] "double"
> typeof(f)
[1] "integer"
값 것은 합니다.f
이용할 수 있는.는 것을 알 수 있습니다.f
에는 정수 값 1, 2, 3, 4 및 레이블 목록("A", "B", "C", "D")과 클래스 속성 "인자"의 두 가지 속성만 포함됩니다.그 이상은 아닙니다.
> str(f)
Factor w/ 4 levels "A","B","C","D": 2 1 3 2 1 4 1 4
> attributes(f)
$levels
[1] "A" "B" "C" "D"
$class
[1] "factor"
원래 값으로 되돌리려면 요인을 생성하는 데 사용되는 수준 값을 알아야 합니다. 이우경c(10, 20, 30, 40)
원래 수준을 올바른 순서로 알면 원래 값으로 되돌릴 수 있습니다.
> orig_levels <- c(10, 20, 30, 40)
> x1 <- orig_levels[f]
> all.equal(x, x1)
[1] TRUE
또한 원래 데이터에서 가능한 모든 값에 대해 레이블이 정의된 경우에만 작동합니다.
따라서 원래 값이 필요한 경우에는 값을 유지해야 합니다.그렇지 않으면 요인으로부터만 해당 정보를 얻을 수 없을 가능성이 높습니다.
사용할 수 있습니다.hablar::convert
데이터 프레임이 있는 경우.구문은 간단합니다.
샘플 df
library(hablar)
library(dplyr)
df <- dplyr::tibble(a = as.factor(c("7", "3")),
b = as.factor(c("1.5", "6.3")))
해결책
df %>%
convert(num(a, b))
제공:
# A tibble: 2 x 2
a b
<dbl> <dbl>
1 7. 1.50
2 3. 6.30
또는 하나의 열을 정수로 지정하고 하나의 숫자로 지정하려면 다음을 수행합니다.
df %>%
convert(int(a),
num(b))
결과:
# A tibble: 2 x 2
a b
<int> <dbl>
1 7 1.50
2 3 6.30
strtoi()
요인 수준이 정수이면 효과가 있습니다.
경기에 늦게, 우연히, 나는 발견했습니다.trimws()
변환할 수 있습니다.factor(3:5)
c("3","4","5")
그럼 전화하셔도 됩니다.as.numeric()
즉, 다음과 같습니다.
as.numeric(trimws(x_factor_var))
type.convert(f)
수준이 완전히 숫자인 요인에 대한 또 다른 기본 옵션입니다.
성능 측면에서는 다음과 같습니다.as.numeric(as.character(f))
하지만 그렇게 빠르지는 않습니다.as.numeric(levels(f))[f]
.
identical(type.convert(f), as.numeric(levels(f))[f])
[1] TRUE
즉, 첫 번째 인스턴스에서 벡터가 요인으로 생성된 이유가 해결되지 않은 경우(즉, 숫자로 강제할 수 없는 일부 문자가 포함되었을 가능성이 있음) 이 접근 방식은 작동하지 않고 요인을 반환합니다.
levels(f)[1] <- "some character level"
identical(type.convert(f), as.numeric(levels(f))[f])
[1] FALSE
만약 당신이 많다면.factor
로 할 열numeric
,
df <- rapply(df, function(x) as.numeric(levels(x))[x], "factor", how = "replace")
이 솔루션은 다음과 같은 경우에 강력합니다.data.frames
모든 요인 수준이 숫자인 경우 혼합 유형을 포함합니다.
찾았습니다as.numeric(levels(f))[f]
정역 구문을 사용하여 열 이름 목록에 적용하기가 어렵습니다.먼저 문자로 변환한 다음 정수를 사용하면 패키지를 추가하지 않고도 원래 숫자 값을 얻을 수 있습니다.아마도 가장 성능이 우수한 솔루션은 아니지만, 단순하고 읽기 쉬운 솔루션을 유지할 수 있습니다.
library(tidyverse)
tbl_df <- tibble(a = as.factor(c("7", "3")),
b = as.factor(c("1.5", "6.3")))
cols <- c("a", "b")
tbl_df %>%
mutate(across(all_of(cols), as.character)) %>%
mutate(across(all_of(cols), as.numeric))
제가 읽을 수 있는 많은 답변들 중에서 주어진 유일한 방법은 요인의 수에 따라 변수의 수를 확장하는 것이었습니다.수준이 "dog"와 "cat"인 변수 "pet"이 있으면 pet_dog 및 pet_cat이 됩니다.
이 경우 요인 변수를 숫자 변수로 변환하여 cat=1 및 dog=0과 같은 여러 수준의 변수에 적용할 수 있는 방식으로 동일한 수의 변수를 유지하고자 했습니다.
아래에서 해당 솔루션을 찾으십시오.
crime <- data.frame(city = c("SF", "SF", "NYC"),
year = c(1990, 2000, 1990),
crime = 1:3)
indx <- sapply(crime, is.factor)
crime[indx] <- lapply(crime[indx], function(x){
listOri <- unique(x)
listMod <- seq_along(listOri)
res <- factor(x, levels=listOri)
res <- as.numeric(res)
return(res)
}
)
.numeric(수준(f))[f] 솔루션이 R 4.0에서 더 이상 작동하지 않는 것 같습니다.
대체 솔루션:
factor2number <- function(x){
data.frame(levels(x), 1:length(levels(x)), row.names = 1)[x, 1]
}
factor2number(yourFactor)
언급URL : https://stackoverflow.com/questions/3418128/how-to-convert-a-factor-to-integer-numeric-without-loss-of-information
'programing' 카테고리의 다른 글
외부 키는 SQL Server에서 자동으로 인덱싱됩니까? (0) | 2023.07.15 |
---|---|
날짜 사이의 Excel SUMIF (0) | 2023.07.15 |
순수한 TypeScript 프로젝트에서 "ReferenceError: exports is not defined"를 수정하는 방법은 무엇입니까? (0) | 2023.07.15 |
시퀀스 번호, 잘못된 번호 (0) | 2023.07.15 |
Xcode 12.3: iOS 시뮬레이터를 위한 빌드이지만, 링크되고 내장된 프레임워크는 iOS + iOS 시뮬레이터를 위해 빌드되었습니다. (0) | 2023.07.15 |