R 计算小数点和第一个非零数字之间的前导零

R 计算小数点和第一个非零数字之间的前导零,r,regex,desctools,R,Regex,Desctools,假设我们有一个数字1.000633,我想计算小数点后的零数,直到分数中的第一个非零数字,答案应该是3。对于0.002,答案应为2 在R中没有这样的函数可以提供帮助。我在package DescTools中探索了Ndec功能,但它不起作用。使用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

假设我们有一个数字1.000633,我想计算小数点后的零数,直到分数中的第一个非零数字,答案应该是3。对于0.002,答案应为2


在R中没有这样的函数可以提供帮助。我在package DescTools中探索了Ndec功能,但它不起作用。

使用
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
#测试值

我们可以使用
sub

ifelse(grepl("\\.0", str1), 
    nchar(sub("[^\\.]+\\.(0+)[^0]+.*", "\\1", str1)), NA)
#[1] 3 2 3 3 2
 nchar(sub(".*\\.(0*).*","\\1",str1))
[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
库(stringi)

r1还有一种可能性:

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

stringr
package中的
stru count

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

x使用
regexpr
及其
match.length
参数

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

attr(regexpr)((?您可以使用
sub
,因为我们不需要跳转。因此不需要
gsub

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


str1再次感谢您,尝试使用str1您可能需要编辑您的第一个解决方案,因为它是错误的。@akrun可能有任何数字,这应该适用于所有数字。几乎每个人的答案下都有一条关于可能问题的评论,而不仅仅是您。请参阅并举例说明您的意思:“好的,Jaap也在线。”“?只需在数字的其他部分中允许除0以外的数字,如
”[^\.]+\.(0+[^0]{1}.*.
,就可以找到它(尽管我仍然更喜欢RHertel的
数字方法)。”.这是一个精确解的问题,而不是upvote@zx8754现在更好了..?即使有0.001的问题,我也喜欢这个解决方案。我想你忘了对它进行矢量化,因为现在它只对长度为1的向量有效…Myabe这应该是
ifelse(圆形(y)=y,-y-1,-天花板(y))
?不是列,只是几个值,例如
x我想知道为什么我的答案下面有两条注释,内容是“它不起作用”。事实上,它确实有效。欢迎使用Stack Overflow,感谢您回答此问题。因为没有注释的代码往往不是很有教育意义,我们希望您添加一些解释,说明这是如何回答此问题的。谢谢!是的,这是最佳解决方案。但是,您应该考虑以下整数日志值:
 count0对于
x@RHertel,如果不匹配,它总是返回
-1
。这是表示不匹配的
regexpr
符号。我的解决方案适用于任何数字。好吧,我理解这一点-就像我理解为什么我的原始帖子需要更正一样。我只是不确定这是否对应于OP请求的输出(“.计算小数点后的零数,直到第一个非零数字…”)。零的负计数对我来说似乎没有多大意义。@RHertel如果需要,可以很容易地用矢量化的方式解决这个问题,但在这种情况下,对于不匹配的情况,-1或0对我来说似乎同样合适。@RHertel只需使用
(?哇。这个问题很快就升级了!:)。我用了OP提到的两个案例。我会尽快修改。谢谢@davidernburgy。怎么样
attr(regexpr("(?<=\\.)0+", x, perl = TRUE), "match.length")
floor( -log10( eps + abs(x) - floor( abs( x ) ) ) )
 nchar(sub(".*\\.(0*).*","\\1",str1))
[1] 3 2 3 3 2
str1 <- as.character(c(1.000633, 0.002, 0.000633,
                   10.000633, 3.0069006))