2015-10-22 21 views
5

1:10000 arasında bir tamsayı verisi var. Onları 0:1 aralığına getirmem gerek. dönüştürme ÖrneğinTam sayıları ondalık değerlere dönüştür

,

  • 12 -> 0,123
  • 1234 - -> 0.12
  • 123> 0,1234

vb (Not yapmak değil scale değerini girin).

Tüm verileri tek seferde nasıl yapacağınızı öneriniz?

+5

Herhangi bir matematik olmadan "as.numeric" yapınız (paste0 (".", X)) ' –

+0

12 ve 1200'ün eşit olduğu anlamına mı geliyor? – DatamineR

+0

@DatamineR evet. – SlightlyBuilt

cevap

10

ben sadece

x/10^ceiling(log10(x)) 

Benchmark

@Frank tarafından sunulan

x <- c(2, 14, 128, 1940, 140, 20000) 
x/10^nchar(x) 
## [1] 0.200 0.140 0.128 0.194 0.140 0.200 

Ama (character dönüşüm önler) çok daha hızlı bir yaklaşım yapacağını

library(microbenchmark) 

set.seed(123) 
x <- sample(1e8, 1e6) 

microbenchmark(
    david = x/10^nchar(x), 
    davidfrank = x/10^ceiling(log10(x)), 
    richard1 = as.numeric(paste0(".", x)), 
    richard2 = as.numeric(sprintf(".%d", x)) 
) 

# Unit: milliseconds 
#  expr  min  lq  mean median  uq  max neval cld 
#  david 691.0513 822.6482 1052.2473 956.5541 1153.4779 2391.7856 100 b 
# davidfrank 130.0522 164.3227 255.8397 197.3158 339.3224 576.2255 100 a 
# richard1 1130.5160 1429.8314 1972.2624 1689.8454 2473.6409 4791.0558 100 c 
# richard2 712.8357 926.8013 1181.5349 1103.1661 1315.4459 2753.6795 100 b 
+3

Çünkü sen zekisin. Öyle değil, bu yüzden kolay yolu seçiyorum. –

+2

Benzer şekilde çalışıyordum, doğru anlayamadım. İyi şeyler. – akrun

+2

Benzer bir şey göndermek üzereydi; "x" karakterini "karakter" e zorlamaktan kaçınmak için: x/(10^findInterval (x, c (0, 10^(1: nchar (maks (x)))))) –

10

El ile olmayan bir yol, ondalık değeri paste() ile eklemek ve ardından sayısal olarak geri yüklemek olabilir.

x <- c(2, 14, 128, 1940, 140, 20000) 
as.numeric(paste0(".", x)) 
# [1] 0.200 0.140 0.128 0.194 0.140 0.200 

Güncelleme 1: İki orijinal olarak yayınlanan yöntemlerin zamanlamaları hakkında bazı ilgi vardı. Aşağıdaki kriterlere göre, yaklaşık aynı görünüyorlar.

library(microbenchmark) 

x <- 1:1e5 
microbenchmark(
     david = { david <- x/10^nchar(x) }, 
    richard = { richard <- as.numeric(paste0(".", x)) } 
) 
# Unit: milliseconds 
#  expr  min  lq  mean median  uq  max neval 
# david 88.94391 89.18379 89.70962 89.40736 89.71012 99.68126 100 
# richard 87.89776 88.17234 89.38383 88.44439 88.77052 105.06066 100 

identical(richard, david) 
# [1] TRUE 

Güncelleme 2: Ben de sprintf() genellikle daha hızlı paste0() daha hatırlardım. Aşağıdakileri de kullanabiliriz. aşağıda gösterildiği gibi Şimdi yukarıdan aynı x kullanarak ve sadece bu iki seçenek karşılaştıran

as.numeric(sprintf(".%d", x)) 

biz paste() karşı sprintf() zamanlaması iyi bir gelişme var.

microbenchmark(
    paste0 = as.numeric(paste0(".", x)), 
    sprintf = as.numeric(sprintf(".%d", x)) 
) 
# Unit: milliseconds 
#  expr  min  lq  mean median  uq  max neval 
# paste0 87.89413 88.41606 90.25795 88.82484 89.65674 107.8080 100 
# sprintf 61.16524 61.23328 62.26202 61.29192 61.48316 79.1202 100 
+0

Harika bir iş! problem çözüldü – SlightlyBuilt

+3

@SlightlyBuilt Bu gerçekten istediğin gibi mi? 2 -> .2 şimdi 140 -> .140'dan daha büyük mü? Sadece neden böyle bir şey isteyeceğini anlamıyorum. – DunderChief

+0

@DunderChief aslında bir meslektaşının hatasıydı :) ve şükürler olsun ki hızlı bir çözüm vardı! – SlightlyBuilt

İlgili konular