Проверьте, является ли число целым - PullRequest
84 голосов
/ 13 августа 2010

Я был удивлен, узнав, что 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)
}

Где мой подход потерпит неудачу? Какой была бы ваша работа, если бы вы были в моих гипотетических ботинках?

Ответы [ 10 ]

103 голосов
/ 13 августа 2010

Другой альтернативой является проверка дробной части:

x%%1==0

или, если вы хотите проверить в пределах определенного допуска:

min(abs(c(x%%1, x%%1-1))) < tol
27 голосов
/ 17 октября 2011

Вот решение с использованием более простых функций и без хаков:

all.equal(a, as.integer(a))

Более того, вы можете протестировать целый вектор, если хотите.Вот функция:

testInteger <- function(x){
  test <- all.equal(x, as.integer(x), check.attributes = FALSE)
  if(test == TRUE){ return(TRUE) }
  else { return(FALSE) }
}

Вы можете изменить ее на *apply в случае векторов, матриц и т. Д.

9 голосов
/ 15 октября 2010

Вот один, по-видимому, надежный способ:

check.integer <- function(N){
    !grepl("[^[:digit:]]", format(N,  digits = 20, scientific = FALSE))
}

check.integer(3243)
#TRUE
check.integer(3243.34)
#FALSE
check.integer("sdfds")
#FALSE

Это решение также допускает целые числа в научной нотации:

> check.integer(222e3)
[1] TRUE
9 голосов
/ 13 августа 2010

Читая документацию по языку R, as.integer больше относится к тому, как хранится число, чем если оно практически эквивалентно целому числу. is.integer проверяет, объявлено ли число как целое число. Вы можете объявить целое число, поставив L после него.

> is.integer(66L)
[1] TRUE
> is.integer(66)
[1] FALSE

Также такие функции, как round, будут возвращать объявленное целое число, что вы и делаете с x==round(x). Проблема с этим подходом состоит в том, что вы считаете практически целым числом. В примере используется меньшая точность для проверки эквивалентности.

> is.wholenumber(1+2^-50)
[1] TRUE
> check.integer(1+2^-50)
[1] FALSE

Так что, в зависимости от вашего приложения, вы можете попасть в неприятности таким образом.

8 голосов
/ 13 августа 2010

Похоже, что вы не видите необходимости учитывать некоторые ошибки. Это не будет необходимо, если все целые числа будут введены как целые числа, однако иногда они появляются в результате арифметических операций, которые теряют некоторую точность. Например:

> 2/49*49
[1] 2
> check.integer(2/49*49)
[1] FALSE 
> is.wholenumber(2/49*49)
[1] TRUE

Обратите внимание, что это не слабость R, все компьютерные программы имеют некоторые пределы точности.

6 голосов
/ 28 октября 2010

С Hmisc::spss.get:

all(floor(x) == x, na.rm = TRUE)

гораздо более безопасный вариант, ИМХО, поскольку он "обходит" проблему точности станка. Если вы попробуете is.integer(floor(1)), вы получите FALSE. Кстати, ваше целое число не будет сохранено как целое, если оно больше значения .Machine$integer.max, которое по умолчанию равно 2147483647, поэтому либо измените значение integer.max, либо выполните альтернативные проверки ...

3 голосов
/ 24 июля 2017

Вы можете использовать простые условия, например:

if(round(var) != var)­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
1 голос
/ 11 ноября 2017

В R, числовое или целое число может быть определено функцией класса. Как правило, все числа хранятся в виде чисел, и чтобы явно определить число как целое число, нам нужно указать «L» после числа.

Пример:

x <- 1 </p>

Класс (х)

[1] "числовой"

х <- 1 л </p>

класс (х)

[1] "целое число"

Надеюсь, это то, что было нужно. Спасибо:)

0 голосов
/ 21 июня 2019

Если вы предпочитаете не писать свою собственную функцию, попробуйте check.integer из пакета installr .

В настоящее время использует ответ ВитошКа.

0 голосов
/ 13 августа 2010

Я не уверен, чего вы пытаетесь достичь. Но вот несколько мыслей:
1. Преобразовать в целое число:
num = as.integer(123.2342)
2. Проверьте, является ли переменная целым числом:
is.integer(num)<br> typeof(num)=="integer"

...