Я был удивлен, узнав, что в R нет удобной функции для проверки целого числа.
is.integer(66) # FALSE
Эти файлы справки предупреждает :
is.integer(x)
не проверяет,x
содержит ли целые числа! Для этого используйтеround
, как в функцииis.wholenumber(x)
в примерах.
В примере эта настраиваемая функция используется в качестве «обходного пути».
is.wholenumber <- function(x, tol = .Machine$double.eps^0.5) abs(x - round(x)) < tol
is.wholenumber(1) # is TRUE
Если бы мне пришлось написать функцию для проверки целых чисел, предполагая, что я не читал приведенные выше комментарии, я бы написал функцию, которая выполняла бы что-то вроде
check.integer <- function(x) {
x == round(x)
}
Где мой подход потерпит неудачу? Что бы вы сделали, если бы были на моем гипотетическом месте?
round(x)
будет реализовано правильно, результатом его применения к целому числу всегда будет это целое число ...is.integer
проверяет вычислительную концепцию,check.integer
пользовательская функция проверяет математическую точку зрения.Ответы:
Другой вариант - проверить дробную часть:
или, если вы хотите проверить в пределах определенного допуска:
источник
x <- 5-1e-8; x%%1
дает 0.9999999 (что означало бы , еслиtol==1e-5
, например) , чтоx
это не является целым числом.min(abs(c(x%%1, x%%1-1))) < tol
аabs(min(x%%1, x%%1-1)) < tol
не иначе, вы получитеFALSE
за любое целое число ...as.integer(x) == x
? Он не отклонит 3 или 3,0, какis.integer(x)
хотел бы, а поймает 3,1.Вот решение, использующее более простые функции и никаких хаков:
Более того, вы можете протестировать сразу весь вектор, если хотите. Вот функция:
Вы можете изменить его для использования
*apply
в случае векторов, матриц и т. Д.источник
if
else
можно было сделать простоisTRUE(test)
. В самом деле, это все, что вам нужно для заменыif
else
предложения иreturn
операторов, поскольку R автоматически возвращает результат последней оценки.testInteger(1.0000001)
[1] ЛОЖЬtestInteger(1.00000001)
[1] ИСТИНАall(a == as.integer(a))
обходит эту проблему! 'Чтение документации на языке R
as.integer
больше связано с тем, как хранится число, чем если оно практически эквивалентно целому числу.is.integer
проверяет, объявлено ли число как целое. Вы можете объявить целое число, поставивL
после него.Также такие функции, как
round
возвращают объявленное целое число, что вы и делаетеx==round(x)
. Проблема с этим подходом заключается в том, что вы считаете практически целым числом. В примере используется меньшая точность для проверки эквивалентности.Так что, в зависимости от вашего приложения, у вас могут возникнуть проблемы.
источник
Вот один, по-видимому, надежный способ:
Это решение также позволяет использовать целые числа в экспоненциальной нотации:
источник
check.integer(1e4)
ИСТИНА, аcheck.integer(1e5)
ЛОЖЬ.is.wholenumber
любое другое решение, представленное в других ответах. Они не должны быть разными:check.integer(1e22); check.integer(1e23)
. Очевидно, вы можете изменить регулярное выражение, чтобы исправить это, но этот подход ужасен. (Комментарий предоставлен авторством в пакете установщика.)format(40, scientific = FALSE, digits = 20)
вместо этого. Я обновил ответ. Спасибо, что заметили это.1.0000000000000001 == 1L [1] TRUE
. Но мое решение лучше, если вы уже получили число в строковой формеcheck.integer("1000000000000000000000000000000000001") [1] TRUE
Похоже, что вы не видите необходимости включать некоторую устойчивость к ошибкам. В этом не было бы необходимости, если бы все целые числа вводились как целые числа, однако иногда они появляются в результате арифметических операций, которые теряют некоторую точность. Например:
Обратите внимание, что это не слабость R, все компьютерные программы имеют некоторые пределы точности.
источник
Откуда
Hmisc::spss.get
:ИМХО гораздо более безопасный вариант, поскольку он "обходит" проблему точности станка. Если попробуешь
is.integer(floor(1))
, получишьFALSE
. Кстати, ваше целое число не будет сохранено как целое, если оно больше.Machine$integer.max
значения, которое по умолчанию составляет 2147483647, поэтому либо изменитеinteger.max
значение, либо выполните альтернативные проверки ...источник
x <- sqrt(2)^2
, тоall(floor(x) == x, na.rm = TRUE)
вернемсяFALSE
вы можете использовать простое условие if, например:
источник
В R, является ли число числовым или целым, можно определить функцией класса. Как правило, все числа хранятся как числовые, и чтобы явно определить число как целое, нам нужно указать «L» после числа.
Пример:
[1] "числовой"
[1] "целое число"
Надеюсь, это то, что было нужно. Спасибо :)
источник
[ОБНОВЛЕНИЕ] ================================================= ===============
Что касается [СТАРОГО] ответа здесь ниже, я обнаружил, что это сработало, потому что я поместил все числа в один атомарный вектор; один из них был персонажем, поэтому каждый стал персонажем.
Если мы используем список (следовательно, принуждение не происходит), все тесты проходят правильно, кроме одного:,
1/(1 - 0.98)
который остаетсяnumeric
. Это потому, чтоtol
параметр установлен по умолчанию,100 * .Machine$double.eps
и это число далеко50
не меньше его удвоения. Итак, в основном для таких чисел у нас есть определить нашу терпимость!Так что если вы хотите, чтобы все испытания стали
TRUE
, вы можетеassertive::is_whole_number(x, tol = 200 * .Machine$double.eps)
В любом случае, я подтверждаю, что напористый IMO остается лучшим решением.
Ниже представлен пример этого [ОБНОВЛЕНИЕ].
Создано 23.07.2019 пакетом REPEX (v0.3.0)
[СТАРЫЙ] =============================================== ==================
IMO лучшее решение исходит из
assertive
пакета (который на данный момент решает все положительные и отрицательные примеры в этом потоке):Создано 23.07.2019 пакетом REPEX (v0.3.0)
источник
Если вы предпочитаете не писать свою собственную функцию, попробуйте
check.integer
из установщика пакетов . В настоящее время используется ответ ВитошКа.Также попробуйте
check.numeric(v, only.integer=TRUE)
из пакета varhandle , который имеет преимущество векторизации.источник
Once также можно использовать
dplyr::near
:Он применяется к любому вектору
a
и имеет необязательный параметр допуска.источник
Я не уверен, чего вы пытаетесь достичь. Но вот некоторые мысли:
1. Преобразовать в целое число:
num = as.integer(123.2342)
2. Проверить, является ли переменная целым числом:
is.integer(num)
typeof(num)=="integer"
источник