當我將因子轉換爲數字或整數時,我獲得的是底層的級別代碼,而不是數值。 html
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
有沒有更好的方法能夠將因子轉換爲數值? spa
R具備許多(未記錄)便利函數,用於轉換因子: code
as.character.factor
as.data.frame.factor
as.Date.factor
as.list.factor
as.vector.factor
可是使人煩惱的是,沒有什麼要處理的因素->數字轉換。 做爲約書亞·烏爾裏希(Joshua Ulrich)答案的延伸,我建議經過定義本身的慣用函數來克服這一遺漏: htm
as.numeric.factor <- function(x) {as.numeric(levels(x))[x]}
您能夠將其存儲在腳本的開頭,甚至能夠存儲在.Rprofile
文件中。 ci
僅在因子標籤與原始值匹配的狀況下纔有可能。 我將用一個例子來解釋。 get
假設數據是向量x
: it
x <- c(20, 10, 30, 20, 10, 40, 10, 40)
如今,我將建立一個帶有四個標籤的因子: io
f <- factor(x, levels = c(10, 20, 30, 40), labels = c("A", "B", "C", "D"))
1) x
是double類型, f
是integer類型。 這是第一個不可避免的信息丟失。 因子始終存儲爲整數。 入門
> typeof(x) [1] "double" > typeof(f) [1] "integer"
2)不可能恢復爲只有f
可用的原始值(十、20、30、40)。 咱們能夠看到f
僅包含整數值一、二、三、4和兩個屬性-標籤列表(「 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
只有在爲原始數據中的全部可能值定義了標籤的狀況下,這才起做用。
所以,若是您須要原始值,則必須保留它們。 不然,頗有可能僅憑一個因素就沒法與他們聯繫。
最簡單的方法是使用包varhandle中的 unfactor
函數
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"
請參閱?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
注意:此特定答案不是用於將數值因子轉換爲數值,而是用於將分類因子轉換爲其相應的級別編號。
這篇文章中的每一個答案都沒法爲我產生結果,正在產生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