因子を数値や整数に変換すると、数値としての値ではなく、基礎となるレベルコードが得られます。
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
本当の値を得るためには、「貼り付け」に頼らなければなりません。
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
]1の警告欄を参照してください。
特に、as.numeric
を factor に適用した場合は意味がありません。
特に、as.numeric
を因子に適用することは無意味であり、暗黙の強制によって
暗黙の強制で起こる可能性があります。 また 因子
f
を次のように変換します。 元の数値に近い値に変換するには に変換するには、as.numeric(levels(f))[f]
が 推奨します。 よりも効率的です。 as.numeric(as.character(f))`よりも効率的です。
Rに関するFAQにも[同様のアドバイスがあります][2]。
**なぜas.numeric(levels(f))[f]
はas.numeric(as.character(f))
よりも効率的なのですか?
as.numeric(as.character(f))は実質的には
as.numeric(levels(f)[f])であり、数値への変換は
nlevels(x)の値ではなく
length(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
[2]: http://cran.r-project.org/doc/FAQ/R-FAQ.html#How-do-I-convert-factors-to-numeric_003f
Rには、係数を変換するための(文書化されていない)便利な関数がいくつかあります。
as.character.factor
.as.data.frame.factor
(データフレーム)。as.Date.factor
(日付因子as.list.factor
(リスト因子)as.vector.factor
(ベクトル因子)しかし、困ったことに、factor -> numeric の変換を処理するものがありません。Joshua Ulrich'氏の回答の延長として、私は独自のイディオム的な関数を定義することでこの不備を克服することを提案します。
as.numeric.factor <- function(x) {as.numeric(levels(x))[x]}
を定義して、スクリプトの最初に置くか、あるいは.Rprofile`ファイルの中に置いておくことを提案します。
これは、ファクターのラベルが元の値と一致している場合にのみ可能です。例を挙げて説明します。
データがベクトル 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"))
x
は double 型,f
は integer 型です.これは最初の避けられない情報の損失です。因子は常に整数として保存されます。> typeof(x)
[1] "double"
> typeof(f)
[1] "integer"
f
だけが利用可能な元の値 (10, 20, 30, 40) に戻すことはできません。f`は整数値1、2、3、4と、ラベルのリスト("A"、"B"、"C"、"D")とクラス属性の"factor"の2つの属性しか持っていないことがわかります。これ以上はありません。> 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
これは、元のデータのすべての可能な値に対してラベルが定義されている場合にのみ機能します。
ですから、元の値が必要な場合は、それらを残しておかなければなりません。そうしないと、ある要因からのみ元に戻せなくなる可能性が高くなります。