В чем разница между целочисленным классом и числовым классом в R


96

Я хочу предисловие к этому, сказав, что я абсолютный новичок в программировании, поэтому, пожалуйста, извините, насколько прост этот вопрос.

Я пытаюсь лучше понять «атомарные» классы в R, и, возможно, это касается классов программирования в целом. Я понимаю разницу между символьными, логическими и сложными классами данных, но мне трудно найти фундаментальную разницу между числовым классом и целочисленным классом.

Скажем, у меня есть простой вектор x <- c(4, 5, 6, 6)целых чисел, было бы разумно, чтобы это был целочисленный класс. Но когда я это сделаю, class(x)я пойму [1] "numeric". Затем, если я конвертирую этот вектор в целочисленный класс x <- as.integer(x). Он возвращает тот же точный список чисел, за исключением того, что класс отличается.

Мой вопрос: почему это так, и почему класс по умолчанию для набора целых чисел является числовым классом, и каковы преимущества и / или недостатки использования целого числа как числового вместо целого.


4
Помогает ли as.integer(c(4.1, 5.2, 6.3, 6.4))вам понять разницу? Вы должны понимать, что внутреннее представление и то, что печатается, совсем не одно и то же. В любом случае, почитайте о типах данных на компьютерных языках.
Роланд

В столбце «Связанные» справа находится следующий вопрос: stackoverflow.com/questions/8804779/…
Мэтью Лундберг,

1
x <- 1; is.integer(x); is.numeric(x)Тогда попробуйте , x <- 1L; is.integer(x); is.numeric(x)и вы сможете увидеть небольшую разницу. Целочисленные классы больше используются для передачи переменных из конструкций C, а также в структурах R. Хотя это еще не все.
Rich Scriven

@Roland Я не думал о классах, определяющих точность. Я привык использовать методы с плавающей запятой для управления целочисленными классами. Это имеет смысл.
Кеон

Ответы:


87

Существует несколько классов, сгруппированных вместе как «числовые» классы, два наиболее распространенных из которых - это двойные (для чисел с плавающей запятой двойной точности) и целые числа. R будет автоматически преобразовывать числовые классы, когда это необходимо, поэтому по большей части для обычного пользователя не имеет значения, хранится ли число 3 в настоящее время как целое или как двойное. Большая часть математических вычислений выполняется с использованием двойной точности, поэтому часто это хранилище по умолчанию.

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


47

Во-первых, вполне реально успешно использовать R в течение многих лет и не нужно знать ответ на этот вопрос. R обрабатывает различия между (обычными) числами и целыми числами в фоновом режиме.

> is.numeric(1)

[1] TRUE

> is.integer(1)

[1] FALSE

> is.numeric(1L)

[1] TRUE

> is.integer(1L)

[1] TRUE

(Если поставить заглавную букву L после целого числа, оно будет сохранено как целое.)

Как видите, «целое число» - это подмножество «числового».

> .Machine$integer.max

[1] 2147483647

> .Machine$double.xmax

[1] 1.797693e+308

Целые числа могут быть немногим более 2 миллиардов, в то время как другие числа могут быть намного больше. Они могут быть больше, поскольку хранятся как числа с плавающей запятой двойной точности. Это означает, что число хранится в двух частях: показатель степени (как 308 выше, за исключением основания 2, а не основания 10) и «мантисса» (как 1,797693 выше).

Обратите внимание, что is.integer - это не проверка того, есть ли у вас целое число, а проверка того, как хранятся данные.

Следует обратить внимание на то, что оператор двоеточия,, :будет возвращать целые числа, если начальная и конечная точки являются целыми числами. Например, 1:5создает integerвектор чисел от 1 до 5. Букву добавлять не нужно L.

> class(1:5)
[1] "integer"

Ссылка: https://www.quora.com/What-is-the-difference-between-numeric-and-integer-in-R


11
Взято именно из сообщения Quora. Верно? Вы могли просто упомянуть ссылку!
Srujan Barai


4

Чтобы процитировать страницу справки (попробуйте ?integer), выделенная жирным шрифтом часть моя:

Целочисленные векторы существуют для того, чтобы данные можно было передавать в код C или Fortran, который их ожидает, и чтобы (небольшие) целочисленные данные могли быть представлены точно и компактно .

Обратите внимание, что текущие реализации R используют 32-битные целые числа для целочисленных векторов, поэтому диапазон представимых целых чисел ограничен примерно +/- 2 * 10 ^ 9: двойные числа могут точно содержать гораздо большие целые числа.

Как сказано на странице справки, R - integerэто 32-битные числа со знаком, поэтому они могут занимать от -2147483648 до +2147483647 и занимать 4 байта.

R numericидентичен 64-битному, doubleсоответствующему стандарту IEEE 754. R не имеет типа данных с одинарной точностью. (источник: справочные страницы numericи double). Двойное значение может хранить все целые числа от -2 ^ 53 до 2 ^ 53 точно без потери точности.

Мы можем видеть размеры типов данных, включая накладные расходы вектора ( источника ):

> object.size(1:1000)
4040 bytes
> object.size(as.numeric(1:1000))
8040 bytes

1

Насколько я понимаю, мы не объявляем переменную с типом данных, поэтому по умолчанию R установил любое число без L как числовое. Если вы написали:

> x <- c(4L, 5L, 6L, 6L)
> class(x)
>"integer" #it would be correct

Пример целого числа:

> x<- 2L
> print(x)

Пример Numeric (вроде как double / float из других языков программирования)

> x<-3.4
> print(x)

следите за диапазоном, например, 1:5будет создавать целые числа.
qwr 01
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.