Most efficient way to extract the number in the 100ths decimal place in R
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
精彩评论