在 r 中找到有效数字与小数点后的数字
finding the number of significant digits versus digits after decimal in r
我想在一个具有不同标度的数字向量中找出有效数字的个数。
例如,数字1000有1个数字;
数字100也有1。数字1300有2.
不要将这与小数点后的位数混淆,后者在这两种情况下都等于 0。
我认为这可行。如果你有像 100000 这样的数字,你需要通过设置选项 (scipen = 999) 来阻止 R 使用像 1e5 这样的科学记数法。另外,在这里你 post 你不关心小数点后的数字。在这里我假设你没有带小数点的数字,但如果你有,你可以先做 floor(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
你可以试试
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
我已经稍微调整了 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)
}
此函数会将向量中的每个值转换为字符值,删除所有前导零、尾随零和小数位,并计算剩余的字符数。它的性能似乎与 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)
注意事项:
此函数returns既不是前导零也不是尾随零的数字的数量。这与有效数字的数量不完全相同。虽然前导零从不重要,但尾随零可能重要也可能不重要——决定它们是否重要需要一些关于测量精度的知识。我建议阅读有关 "Significant Figures" 的维基百科文章以获取更多详细信息。
我想在一个具有不同标度的数字向量中找出有效数字的个数。
例如,数字1000有1个数字; 数字100也有1。数字1300有2.
不要将这与小数点后的位数混淆,后者在这两种情况下都等于 0。
我认为这可行。如果你有像 100000 这样的数字,你需要通过设置选项 (scipen = 999) 来阻止 R 使用像 1e5 这样的科学记数法。另外,在这里你 post 你不关心小数点后的数字。在这里我假设你没有带小数点的数字,但如果你有,你可以先做 floor(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
你可以试试
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
我已经稍微调整了 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)
}
此函数会将向量中的每个值转换为字符值,删除所有前导零、尾随零和小数位,并计算剩余的字符数。它的性能似乎与 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)
注意事项:
此函数returns既不是前导零也不是尾随零的数字的数量。这与有效数字的数量不完全相同。虽然前导零从不重要,但尾随零可能重要也可能不重要——决定它们是否重要需要一些关于测量精度的知识。我建议阅读有关 "Significant Figures" 的维基百科文章以获取更多详细信息。