Bir faktörü sayısal veya tamsayıya dönüştürdüğümde, değerleri sayı olarak değil, temel seviye kodlarını alıyorum.
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
Gerçek değerleri elde etmek için yapıştır
yöntemine başvurmam gerekiyor:
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
Bir faktörü sayısal değere dönüştürmenin daha iyi bir yolu var mı?
Bkz. ?factor
'in Uyarı bölümü:
Özellikle,
as.numeric
aşağıdakilere uygulanır bir faktör anlamsızdır ve Örtülü zorlama ile gerçekleşir. için birf
faktörünü yaklaşık olarak orijinal sayısal değerler,as.numeric(levels(f))[f]
ise tavsiye edilir ve biraz daha fazlası daha verimlias.numeric(as.character(f))
.
R ile ilgili SSS benzer tavsiyelere sahiptir.
**Neden as.numeric(levels(f))[f]
, as.numeric(as.character(f))
den daha verimlidir?
as.numeric(as.character(f))etkin bir şekilde
as.numeric(levels(f)[f])dir, bu nedenle
nlevels(x)değerleri yerine
length(x)` değerleri üzerinde sayısal dönüştürme gerçekleştirirsiniz. Hız farkı en çok az seviyeli uzun vektörler için belirgin olacaktır. Değerler çoğunlukla benzersizse, hızda çok fazla fark olmayacaktır. Dönüştürmeyi nasıl yaparsanız yapın, bu işlemin kodunuzda darboğaz yaratması pek olası değildir, bu nedenle bu konuda çok fazla endişelenmeyin.
Bazı zamanlamalar
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, faktörleri dönüştürmek için bir dizi (belgelenmemiş) kolaylık fonksiyonuna sahiptir:
as.character.factor
as.data.frame.factor
as.Date.factor
as.list.factor
as.vector.factor
Ancak can sıkıcı bir şekilde, factor -> numeric dönüşümünü idare edecek hiçbir şey yoktur. Joshua Ulrich'in cevabının bir uzantısı olarak, bu ihmalin üstesinden kendi deyimsel fonksiyonunuzu tanımlayarak gelmenizi öneririm:
as.numeric.factor <- function(x) {as.numeric(levels(x))[x]}
komut dosyanızın başında veya daha da iyisi .Rprofile
dosyanızda saklayabilirsiniz.
Faktör etiketlerinin orijinal değerlerle eşleşmesi durumunda sadece mümkündür. Bunu bir örnekle açıklayacağım.
Verilerin x
vektörü olduğunu varsayalım:
x <- c(20, 10, 30, 20, 10, 40, 10, 40)
Şimdi dört etiketli bir faktör oluşturacağım:
f <- factor(x, levels = c(10, 20, 30, 40), labels = c("A", "B", "C", "D"))
x
double tipindedir, f
ise integer tipindedir. Bu ilk kaçınılmaz bilgi kaybıdır. Çarpanlar her zaman tamsayı olarak saklanır.> typeof(x)
[1] "double"
> typeof(f)
[1] "integer"
f
mevcutken orijinal değerlere (10, 20, 30, 40) geri dönmek mümkün değildir. f`nin yalnızca 1, 2, 3, 4 tamsayı değerlerini ve iki özniteliği tuttuğunu görebiliriz - etiket listesi ("A", "B", "C", "D") ve sınıf özniteliği "factor". Başka bir şey yok.> 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"
Orijinal değerlere geri dönmek için faktörü oluştururken kullanılan seviyelerin değerlerini bilmemiz gerekir. Bu durumda c(10, 20, 30, 40)
. Eğer orijinal seviyeleri biliyorsak (doğru sırada), orijinal değerlere geri dönebiliriz.
> orig_levels <- c(10, 20, 30, 40)
> x1 <- orig_levels[f]
> all.equal(x, x1)
[1] TRUE
Ve bu yalnızca orijinal verilerdeki tüm olası değerler için etiketlerin tanımlanmış olması durumunda işe yarayacaktır.
Dolayısıyla, orijinal değerlere ihtiyacınız olacaksa, bunları saklamanız gerekir. Aksi takdirde, sadece bir faktörden onlara geri dönmenin mümkün olmama ihtimali yüksektir.