Логическая проверка значений вектора с одинаковым приоритетом или нет
У меня есть вектор с переменными элементами, и я хочу проверить, находятся ли последние два элемента в том же порядке цифр.
Например, если последние два вектора равны 0,0194 и 0,0198, возвращаются TRUE
, потому что их порядок цифр после нуля одинаков (порядка 0,01 10^-2).! для другого примера число может быть 0,00014 и 0,00012, поэтому их точность все еще примерно одинакова, функция должна также возвращать TRUE
,
Как мы можем построить логическое утверждение или функцию, чтобы проверить это.
x<- c(0.817104, 0.241665, 0.040581, 0.022903, 0.019478, 0.019846)
2 ответа
Возможно, я слишком обдумываю это, но вы можете проверить, что порядок величины и первая ненулевая цифра идентичны для каждого.
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(... , ...))