我想知道小数点后第一个数字小于5的位置。如果不可能(所有数字都大于或等于5),则应返回数字的小数位数。所以这个数据:
library(dplyr) Data <- tibble(Number = c(0.998971282, 0.97871, 0.98121752874, 0.98921752874, 0.95171358,0.99999999))
应生成如下输出:
Data %>% mutate(Position = c(6, 5, 3, 4, 3, 8))
rsaldnfx1#
基本R
get_first_digit_below <- function(x){ str <- substr(x, 3, nchar(x)) idx <- regexpr("[0-4]", str) idx[idx < 0] <- nchar(str)[idx < 0] as.vector(idx) } get_first_digit_below(Data$Number) #[1] 6 5 3 4 3 8
深度和字符串
library(stringr) library(dplyr) get_first_digit_below <- function(x){ str <- substr(x, 3, nchar(x)) idx <- str_locate(str, "[0-4]")[, 1] coalesce(idx, str_length(str)) } get_first_digit_below(Data$Number) #[1] 6 5 3 4 3 8
esyap4oy2#
避免转换为字符的解决方案。
fFirstDigit <- function(v, x) { n <- -floor(log10(.Machine$double.eps)) m <- matrix(as.integer((rep(v*10^(n - ceiling(log10(v))), each = n)/10^((n - 1L):0))%%10), length(v), n, TRUE) m[,n] <- 0L max.col(m < x, "f") } Number <- c(0.998971282, 0.97871, 0.98121752874, 0.98921752874, 0.95171358, 0.99999999, 1 - .Machine$double.eps, 987654321) fFirstDigit(Number, 5L) #> [1] 6 5 3 4 3 9 16 6
qzlgjiam3#
A基R方法使用strsplit。
strsplit
cbind( Data, Position = sapply(strsplit(as.character(Data$Number), ""), function(x){ is <- as.numeric(x[3:length(x)]) < 5 ifelse(any(is), which(is)[1], length(x[3:length(x)])) }) ) Number Position 1 0.9989713 6 2 0.9787100 5 3 0.9812175 3 4 0.9892175 4 5 0.9517136 3 6 1.0000000 8
dplyr版本
dplyr
library(dplyr) library(stringr) Data %>% rowwise() %>% mutate(n = str_split(Number, ""), n = list(n[3:length(n)]), Position = which(sapply(n, "<", 5))[1], Position = replace_na(Position, length(n)), n = NULL) %>% ungroup() # A tibble: 6 × 2 Number Position <dbl> <int> 1 0.999 6 2 0.979 5 3 0.981 3 4 0.989 4 5 0.952 3 6 1.00 8
bjp0bcyl4#
另一种方法是使用regexec。最后的和加上最后一个匹配的长度(零或一个[0-4]数字),以便如果存在这样的数字,则返回其位置,否则返回十进制数的个数。
regexec
[0-4]
c("0.998971282", "0.97871", "0.98121752874", "0.98921752874", "0.95171358","0.99999999") |> regexec(pattern = "[0-9]+\\.([5-9]+)([0-4])?") |> sapply(FUN= attr, which = "match.length") |> (\(z) {z[2,] + z[3,]})() [1] 6 5 3 4 3 8
4条答案
按热度按时间rsaldnfx1#
基本R
深度和字符串
esyap4oy2#
避免转换为字符的解决方案。
qzlgjiam3#
A基R方法使用
strsplit
。dplyr
版本bjp0bcyl4#
另一种方法是使用
regexec
。最后的和加上最后一个匹配的长度(零或一个[0-4]
数字),以便如果存在这样的数字,则返回其位置,否则返回十进制数的个数。