667

因子を数値または整数に変換すると、数値としての値ではなく、基になるレベル コードが取得されます。

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

因子を数値に変換するより良い方法はありますか?

4

11 に答える 11

807

の警告セクションを参照してください?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
于 2010-08-05T19:01:13.437 に答える
104

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]}

スクリプトの先頭に保存するか、ファイルに保存することをお勧めし.Rprofileます。

于 2014-03-27T23:39:05.443 に答える
38

最も簡単な方法は、因子ベクトルまたはデータフレームを受け入れることができる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"
于 2015-12-01T14:11:51.273 に答える
10

因子ラベルが元の値と一致する場合にのみ可能です。例を挙げて説明します。

データが vector であると仮定します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は doublef型、integer 型です。これは、最初の避けられない情報の損失です。係数は常に整数として格納されます。

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

2) 元の値 (10、20、30、40) に戻すことはできませfん。fが整数値 1、2、3、4 と 2 つの属性 (ラベルのリスト ("A"、"B"、"C"、"D")) とクラス属性 "factor" のみを保持していることがわかります。これ以上何もない。

> 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

これは、元のデータのすべての可能な値に対してラベルが定義されている場合にのみ機能します。

したがって、元の値が必要な場合は、それらを保持する必要があります。そうしないと、ある要因からのみ元に戻すことができない可能性が高くなります。

于 2015-10-09T12:34:35.647 に答える
2

strtoi()因子水準が整数の場合に機能します。

于 2021-05-06T19:47:47.050 に答える
-1

ソリューション as.numeric(levels(f))[f] は R 4.0 では機能しなくなったようです。

代替ソリューション:

factor2number <- function(x){
    data.frame(levels(x), 1:length(levels(x)), row.names = 1)[x, 1]
}

factor2number(yourFactor)
于 2020-05-24T16:38:36.960 に答える