是否以相同的顺序对向量值进行逻辑检查
logical check of vector values at the same precesion or not
我有一个包含可变元素的向量,我想检查它的最后两个元素是否处于相同的数字顺序。
例如,如果最后两个向量是 0.0194 和 0.0198 return TRUE
。因为它们在零之后的数字顺序是相同的(0.01 顺序 10^-2)。 !对于其他示例,数字可能是 0.00014 和 0.00012,因此它们的精度仍然大致相同,函数应该 return 也 TRUE
。
我们如何构建逻辑语句或函数来检查这一点。
x<- c(0.817104, 0.241665, 0.040581, 0.022903, 0.019478, 0.019846)
我可能想多了,但你可以测试一下每个数量级和第一个非零数字是否相同。
x <- c(0.817104, 0.241665, 0.040581, 0.022903, 0.019478, 0.019846)
oom <- function(x, base = 10) as.integer(ifelse(x == 0, 0, floor(log(abs(x), base))))
oom(x)
# [1] -1 -1 -2 -2 -2 -2
(tr <- trunc(x / 10 ** oom(x, 10)))
# [1] 8 2 4 2 1 1
所以对于最后两个,两者的数量级都是-2,第一个非零数字都是1。
放入函数中:
f <- function(x) {
oom <- function(x, base = 10) as.integer(ifelse(x == 0, 0, floor(log(abs(x), base))))
x <- tail(x, 2)
oo <- oom(x)
tr <- trunc(x / 10 ** oo)
(oo[1] == oo[2]) & (tr[1] == tr[2])
}
## more test cases
x1 <- c(0.019, 0.011)
x2 <- c(0.01, 0.001)
f(x) ## TRUE
f(x1) ## TRUE
f(x2) ## FALSE
这是一个比上面更通用的函数,用于检查最后一个 n
而不是 2
g <- function(x, n = 2) {
oom <- function(x, base = 10) as.integer(ifelse(x == 0, 0, floor(log(abs(x), base))))
x <- tail(x, n)
oo <- oom(x)
tr <- trunc(x / 10 ** oo)
Reduce(`==`, oo) & Reduce(`==`, tr)
}
g(c(.24, .15, .14), 2) ## TRUE
g(c(.24, .15, .14), 3) ## FALSE
@rawr 担心过度思考。我想我也应该。这是我想出的,请注意,这处理了浮点数的打印表示有时具有欺骗性的事实。
orddig <- function(x) which( sapply( 0:16, function(n){ isTRUE(all.equal(x*10^n ,
round(x*10^n,0)))}))[1]
> sapply( c(0.00014 , 0.00012 ), orddig)
[1] 6 6
我最初的努力是使用 signif 函数,但这是不同的数值思维轨迹,因为 0.01 和 0.001 具有相同数量的有效数字。另请注意:
> sapply( 10^5*c(0.00014 , 0.00012 ), trunc, 4)
[1] 13 12
这就是为什么我们需要 isTRUE(all.equal(... , ...))
我有一个包含可变元素的向量,我想检查它的最后两个元素是否处于相同的数字顺序。
例如,如果最后两个向量是 0.0194 和 0.0198 return TRUE
。因为它们在零之后的数字顺序是相同的(0.01 顺序 10^-2)。 !对于其他示例,数字可能是 0.00014 和 0.00012,因此它们的精度仍然大致相同,函数应该 return 也 TRUE
。
我们如何构建逻辑语句或函数来检查这一点。
x<- c(0.817104, 0.241665, 0.040581, 0.022903, 0.019478, 0.019846)
我可能想多了,但你可以测试一下每个数量级和第一个非零数字是否相同。
x <- c(0.817104, 0.241665, 0.040581, 0.022903, 0.019478, 0.019846)
oom <- function(x, base = 10) as.integer(ifelse(x == 0, 0, floor(log(abs(x), base))))
oom(x)
# [1] -1 -1 -2 -2 -2 -2
(tr <- trunc(x / 10 ** oom(x, 10)))
# [1] 8 2 4 2 1 1
所以对于最后两个,两者的数量级都是-2,第一个非零数字都是1。
放入函数中:
f <- function(x) {
oom <- function(x, base = 10) as.integer(ifelse(x == 0, 0, floor(log(abs(x), base))))
x <- tail(x, 2)
oo <- oom(x)
tr <- trunc(x / 10 ** oo)
(oo[1] == oo[2]) & (tr[1] == tr[2])
}
## more test cases
x1 <- c(0.019, 0.011)
x2 <- c(0.01, 0.001)
f(x) ## TRUE
f(x1) ## TRUE
f(x2) ## FALSE
这是一个比上面更通用的函数,用于检查最后一个 n
而不是 2
g <- function(x, n = 2) {
oom <- function(x, base = 10) as.integer(ifelse(x == 0, 0, floor(log(abs(x), base))))
x <- tail(x, n)
oo <- oom(x)
tr <- trunc(x / 10 ** oo)
Reduce(`==`, oo) & Reduce(`==`, tr)
}
g(c(.24, .15, .14), 2) ## TRUE
g(c(.24, .15, .14), 3) ## FALSE
@rawr 担心过度思考。我想我也应该。这是我想出的,请注意,这处理了浮点数的打印表示有时具有欺骗性的事实。
orddig <- function(x) which( sapply( 0:16, function(n){ isTRUE(all.equal(x*10^n ,
round(x*10^n,0)))}))[1]
> sapply( c(0.00014 , 0.00012 ), orddig)
[1] 6 6
我最初的努力是使用 signif 函数,但这是不同的数值思维轨迹,因为 0.01 和 0.001 具有相同数量的有效数字。另请注意:
> sapply( 10^5*c(0.00014 , 0.00012 ), trunc, 4)
[1] 13 12
这就是为什么我们需要 isTRUE(all.equal(... , ...))