在r中找到有效位数与小数点后的数字

时间:2018-04-09 09:57:30

标签: r decimal significant-digits

我想在数字向量中找到有效数字的有效位数。

例如,数字1000有1位数; 数字100也有1.数字1300有2。

这不能与小数点后的位数混淆,在两种情况下都等于0。

4 个答案:

答案 0 :(得分:3)

此函数将向量中的每个值转换为字符值,删除所有前导零,尾随零和小数位,并计算剩余字符数。它的表现似乎与phiver的答案相当。

sigfigs <- function(x){
  orig_scipen <- getOption("scipen")
  options(scipen = 999)
  on.exit(options(scipen = orig_scipen))

  x <- as.character(x)
  x <- sub("\\.", "", x)
  x <- gsub("(^0+|0+$)", "", x)
  nchar(x)
}

x <- c(1000,100,1300, 1200.1, 12345.67, 12345.670)

sigfigs(x)

注意事项

此函数返回既不是前导也不是尾随零的位数。这与有效数字的数量不完全相同。虽然前导零从不显着,但尾随零可能有或没有意义 - 决定它们是否需要一些关于测量精度的知识。我建议阅读维基百科关于“重要数据”的文章以获取更多细节。

答案 1 :(得分:0)

我认为这可行。如果您的数字为100000,则需要通过设置选项(scipen = 999)来阻止R使用科学记数法,如1e5。此外,在这里你发布你不关心小数点后的数字。在这里,我假设你没有带小数点的数字,但如果你这样做,你可以先做(x)。

x <- c(1000,100,1300, 1234,54334,324,1,1,546,12140465,0,100000,10203,20003,20,102030405060,20)

options(scipen = 999)

sapply(x, function(x) {sum(as.numeric(substring(x, 1: nchar(x), 1:nchar(x))) %in% c(1:9))})

这给出了:     [1] 1 1 2 4 5 3 1 1 3 7 0 1 3 2 1 6 1

答案 2 :(得分:0)

你可以尝试

library(tidyverse)
library(stringr)
a <- c(1000,100,1300, 1234,1,0,12140465,1003.02,1003.20,1003.22,0.00001)
tibble(a) %>% 
  mutate(b=format(a, scientific = FALSE)) %>% 
  separate(b, into = c("b1", "b2"), sep = "[.]", remove = F) %>% 
  mutate(b1 = case_when(str_sub(b1, str_length(b1),str_length(b1)) == "0" ~ str_count(b1, "[1-9]"),
                      TRUE ~ str_count(b1, "[0-9]"))) %>% 
  mutate(b2 = str_count(b2, "[1-9]")) %>% 
  mutate(res=b1+b2)
# A tibble: 11 x 5
         a b                   b1    b2   res
     <dbl> <chr>            <int> <int> <int>
 1 1.00e+3 "    1000.00000"     1     0     1
 2 1.00e+2 "     100.00000"     1     0     1
 3 1.30e+3 "    1300.00000"     2     0     2
 4 1.23e+3 "    1234.00000"     4     0     4
 5 1.00e+0 "       1.00000"     1     0     1
 6 0.      "       0.00000"     0     0     0
 7 1.21e+7 12140465.00000       8     0     8
 8 1.00e+3 "    1003.02000"     4     1     5
 9 1.00e+3 "    1003.20000"     4     1     5
10 1.00e+3 "    1003.22000"     4     2     6
11 1.00e-5 "       0.00001"     0     1     1

答案 3 :(得分:0)

我稍微调整了this article中的功能以使其再次运行。所有学分都归该文章的作者所有。该功能可以改进。

代码:

x <- c(1000,100,1300, 1200.1, 12345.67, 12345.670)
sapply(x, FUN = sigdigs)
[1] 1 1 2 5 7 7

功能:

sigdigs <- function(n) {
  i <- 0
  # Check for decimal point is present
  if(length(grep("\\.", as.character(n))) > 0) { # real number
    # Separate integer and fractional parts
    intfrac <- unlist(strsplit(as.character(n), "\\."))
    digstring <- paste(intfrac[1], intfrac[2], sep = "")
    numfigs <- nchar(digstring)
    while(i < numfigs) {
      # Find index of 1st non-zero digit from LEFT
      if(substr(digstring,i+1,i+1) == "0") {
        i <- i + 1
        next
      } else {
        sigfigs <- numfigs - i
        break
      }
    }   
  } else {  # must be an integer      
    digstring <- n
    numfigs <- nchar(digstring)
    while(i < numfigs) {
      # Find index of 1st non-zero digit from RIGHT
      if(substr(digstring, numfigs-i, numfigs-i) == "0") {
        i <- i + 1
        next
      } else {
        sigfigs <- numfigs - i
        break
      }
    }   
  }   
  return(sigfigs)
}