开发者

Most efficient way to extract the number in the 100ths decimal place in R

开发者 https://www.devze.com 2023-03-22 17:40 出处:网络
Here is a rather inefficient way to extract the number. as.integer((x%%floor(x)*100)-(signif(x%%floor(x)*开发者_运维知识库100,1)))

Here is a rather inefficient way to extract the number.

as.integer((x%%floor(x)*100)-(signif(x%%floor(x)*开发者_运维知识库100,1)))

Does anyone else have a better way?


You could try

as.integer(x*100) %% 10


Not sure if it's faster after all the coercion to string and back, but you can try location-based character manipulation:

as.numeric(sub("[-0-9+].[0-9]([0-9]).+","\\1",as.character(x),perl=TRUE)),
as.numeric(substr(strsplit(as.character(x),".",fixed=TRUE)[[1]][2],2,2))

Edit: It turns out it's slower.

x <- runif(1)

re.fxn <- function(x) {
  as.integer(sub("[0-9+].[0-9]([0-9]).+","\\1",as.character(x),perl=TRUE))
}
ss.fxn <- function(x) {
  as.integer(substr(strsplit(as.character(x),".",fixed=TRUE)[[1]][2],2,2))
}
ai.fxn <- function(x) {
  as.integer(x*100) %% 10
}

microbenchmark(
  as.integer((x%%floor(x)*100)-(signif(x%%floor(x)*100,1))),
  as.integer(x*100) %% 10,
  re.fxn(x) ,
  ss.fxn(x),
  ai.fxn(x),
  times=10
  )

                                                              expr    min
1                                                        ai.fxn(x)   5989
2 as.integer((x%%floor(x) * 100) - (signif(x%%floor(x) * 100, 1)))  11121
3                                          as.integer(x * 100)%%10   4278
4                                                        re.fxn(x) 103508
5                                                        ss.fxn(x)  40206
      lq   median     uq    max
1   6844   8555.0   8556  10266
2  12832  12832.5  14543  17965
3   4278   4278.0   5134  11121
4 103509 104364.0 106075 207017
5  41062  42344.5  42773  65869

Seems like a speed win for the modulo. And the difference only narrows slightly if you're looking for higher-order digits in a generic function robust to negative x's:

ss.fxn <- function(x,d=2) {
  as.integer(substr(strsplit(as.character(x),".",fixed=TRUE)[[1]][2],d,d))
}
ai.fxn <- function(x,d=2) {
  as.integer(abs(x)*10^d) %% 10
}
d <- 8
microbenchmark(
  ss.fxn(x,d),
  ai.fxn(x,d),
  times=1000
  )

          expr   min    lq median    uq    max
1 ai.fxn(x, d)  6845  8555  10266 10266  75280
2 ss.fxn(x, d) 40206 41061  41062 41917 284006
0

精彩评论

暂无评论...
验证码 换一张
取 消