将整数转换为十进制值

时间:2015-10-22 19:43:00

标签: r

我在1:10000之间有一组整数数据。我需要将它们放在0:1范围内。

例如,转换

  • 12 - > 0.12
  • 123 - > 0.123
  • 1234 - > 0.1234

等。 (请注意,我不想scale值。)

有关如何同时对所有数据执行此操作的任何建议吗?

2 个答案:

答案 0 :(得分:10)

非mathy方式是使用paste()添加小数,然后强制返回数字。

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

更新1:对两个最初发布的方法的时间安排有一些兴趣。根据以下基准,它们似乎差不多。

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

更新2:我还记得sprintf()通常比paste0()更快。我们也可以使用以下内容。

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

现在使用上面相同的x,并且只比较这两个选项,我们对sprintf()paste()的时间有了很大的改进,如下所示。

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

答案 1 :(得分:10)

我只想做

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

但@Frank提供的更快的方法(避免character转换)

x/10^ceiling(log10(x))

<强>基准

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