program tip

정보 손실없이 계수를 정수 \ 숫자로 변환하는 방법은 무엇입니까?

radiobox 2020. 10. 4. 10:49
반응형

정보 손실없이 계수를 정수 \ 숫자로 변환하는 방법은 무엇입니까?


요인을 숫자 또는 정수로 변환하면 값이 숫자가 아닌 기본 수준 코드를 얻습니다.

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

요인을 숫자로 변환하는 더 좋은 방법이 있습니까?


의 경고 섹션을 참조하십시오 ?factor.

특히 as.numeric요인에 적용하는 것은 의미가 없으며 암시 적 강제에 의해 발생할 수 있습니다. 요인 f을 대략적인 원래 숫자 값으로 변환하려면을 as.numeric(levels(f))[f]권장하며보다 약간 더 효율적 as.numeric(as.character(f))입니다.

R에 대한 FAQ 에도 비슷한 조언이 있습니다.


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.numeric.factor <- function(x) {as.numeric(levels(x))[x]}

스크립트 시작 부분에 저장할 수 있거나 .Rprofile파일에 더 잘 저장할 수 있습니다.


가장 쉬운 방법은 varhandleunfactor 패키지의 함수 를 사용하는 것입니다.

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"

참고 :이 특정 대답이 없는 수치로 숫자 값 요소를 변환, 그것은 그에 상응하는 수준의 번호 범주 요소를 변환하는 것입니다.


이 게시물의 모든 답변은 나를 위해 결과를 생성하지 못했고 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

요인 레이블이 원래 값과 일치하는 경우 에만 가능 합니다. 예를 들어 설명하겠습니다.

데이터가 벡터라고 가정합니다 x.

x <- c(20, 10, 30, 20, 10, 40, 10, 40)

이제 4 개의 레이블이있는 요소를 생성합니다.

f <- factor(x, levels = c(10, 20, 30, 40), labels = c("A", "B", "C", "D"))

1) x is with type double, f is with type integer. This is the first unavoidable loss of information. Factors are always stored as integers.

> typeof(x)
[1] "double"
> typeof(f)
[1] "integer"

2) It is not possible to revert back to the original values (10, 20, 30, 40) having only f available. We can see that f holds only integer values 1, 2, 3, 4 and two attributes - the list of labels ("A", "B", "C", "D") and the class attribute "factor". Nothing more.

> 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"

To revert back to the original values we have to know the values of levels used in creating the factor. In this case c(10, 20, 30, 40). If we know the original levels (in correct order), we can revert back to the original values.

> orig_levels <- c(10, 20, 30, 40)
> x1 <- orig_levels[f]
> all.equal(x, x1)
[1] TRUE

And this will work only in case when labels have been defined for all possible values in the original data.

So if you will need the original values, you have to keep them. Otherwise there is a high chance it will not be possible to get back to them only from a factor.


You can use hablar::convert if you have a data frame. The syntax is easy:

Sample df

library(hablar)
library(dplyr)

df <- dplyr::tibble(a = as.factor(c("7", "3")),
                    b = as.factor(c("1.5", "6.3")))

Solution

df %>% 
  convert(num(a, b))

gives you:

# A tibble: 2 x 2
      a     b
  <dbl> <dbl>
1    7.  1.50
2    3.  6.30

Or if you want one column to be integer and one numeric:

df %>% 
  convert(int(a),
          num(b))

results in:

# A tibble: 2 x 2
      a     b
  <int> <dbl>
1     7  1.50
2     3  6.30

late to the game, accidently, I found trimws() can convert factor(3:5) to c("3","4","5"). Then you can call as.numeric(). That is:

as.numeric(trimws(x_factor_var))

참고URL : https://stackoverflow.com/questions/3418128/how-to-convert-a-factor-to-integer-numeric-without-loss-of-information

반응형