Самый эффективный способ извлечь число с точностью до сотого знака после запятой в R - PullRequest
2 голосов
/ 26 июля 2011

Вот довольно неэффективный способ извлечь число.

as.integer((x%%floor(x)*100)-(signif(x%%floor(x)*100,1)))

У кого-нибудь есть лучший способ?

Ответы [ 2 ]

6 голосов
/ 26 июля 2011

Вы можете попробовать

as.integer(x*100) %% 10
2 голосов
/ 26 июля 2011

Не уверен, быстрее ли это после всех приведений к строке и обратно, но вы можете попробовать манипулирование символами на основе местоположения:

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))

Редактировать: Оказывается, это медленнее.

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

Похоже на скоростную победу по модулю. И разница лишь немного сужается, если вы ищете цифры высшего порядка в обобщенной функции, устойчивой к отрицательным x:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...