Подтвердить что ты не робот

Считайте начальные нули между десятичной точкой и первой ненулевой цифрой

Предположим, что если у нас есть номер 1.000633, я хочу подсчитать количество нулей после десятичной точки до первой отличной от нуля цифры во фракции, ответ должен быть 3. Для 0.002 ответ должен быть 2.

В R нет такой функции, которая могла бы помочь. Я изучил функцию Ndec в пакете DescTools, но он не выполняет эту работу.

4b9b3361

Ответ 1

Используя regexpr и его аргумент match.length

attr(regexpr("(?<=\\.)0+", x, perl = TRUE), "match.length")

Ответ 2

Здесь другая возможность:

zeros_after_period <- function(x) {
if (isTRUE(all.equal(round(x),x))) return (0) # y would be -Inf for integer values
y <- log10(abs(x)-floor(abs(x)))   
ifelse(isTRUE(all.equal(round(y),y)), -y-1, -ceiling(y))} # corrects case ending with ..01

Пример:

x <- c(1.000633, 0.002, -10.01, 7.00010001, 62.01)
sapply(x,zeros_after_period)
#[1] 3 2 1 3 1

Ответ 3

Мы можем использовать sub

ifelse(grepl("\\.0", str1), 
    nchar(sub("[^\\.]+\\.(0+)[^0]+.*", "\\1", str1)), NA)
#[1] 3 2 3 3 2

Или используя stringi

library(stringi)
r1 <- stri_extract(str1, regex="(?<=\\.)0+")
ifelse(is.na(r1), NA, nchar(r1))
#[1] 3 2 3 3 2

Просто, чтобы проверить, работает ли он с любыми странными случаями

str2 <- "0.00A-Z"
nchar(sub("[^\\.]+\\.(0+)[^0]+.*", "\\1", str2))
#[1] 2

данные

str1 <- as.character(c(1.000633, 0.002, 0.000633,
                                  10.000633, 3.0069006))

Ответ 4

Использование функции rle:

#test values
x <- c(0.000633,0.003,0.1,0.001,0.00633044,10.25,111.00012,-0.02)

#result
sapply(x, function(i){
  myNum <- unlist(strsplit(as.character(i), ".", fixed = TRUE))[2]
  myNumRle <- rle(unlist(strsplit(myNum, "")))
  if(myNumRle$values[1] == 0) myNumRle$lengths[1] else 0
})

#output
# [1] 3 2 0 2 2 0 3 1

Ответ 5

Другой способ использования пакета str_count из stringr,

 x <- as.character(1.000633)
 str_count(gsub(".*[.]","",x), "0")
 #[1] 3

EDIT: подсчитывает все нули после десятичного и до первого ненулевого значения.

y <- c(1.00215, 1.010001, 50.000809058, 0.1)
str_count(gsub(".*[.]","",gsub("(?:(0+))[1-9].*","\\1",as.character(y))),"0")
#[1] 2 1 3 0

Ответ 6

floor( -log10( eps + abs(x) - floor( abs( x ) ) ) )