Quelle est la différence entre une classe entière et une classe numérique dans R


93

Je veux commencer en disant que je suis un débutant absolu en programmation, alors veuillez excuser à quel point cette question est fondamentale.

J'essaie d'avoir une meilleure compréhension des classes "atomiques" dans R et peut-être que cela vaut pour les classes de programmation en général. Je comprends la différence entre une classe de données caractère, logique et complexe, mais j'ai du mal à trouver la différence fondamentale entre une classe numérique et une classe entière.

Disons que j'ai un simple vecteur x <- c(4, 5, 6, 6)d'entiers, il serait logique que ce soit une classe entière. Mais quand je le fais, class(x)je reçois [1] "numeric". Ensuite, si je convertis ce vecteur en une classe entière x <- as.integer(x). Il renvoie la même liste exacte de nombres sauf que la classe est différente.

Ma question est pourquoi est-ce le cas, et pourquoi la classe par défaut pour un ensemble d'entiers est une classe numérique, et quels sont les avantages et / ou les inconvénients d'avoir un entier défini comme numérique au lieu d'entier.


4
Cela as.integer(c(4.1, 5.2, 6.3, 6.4))vous aide- t- il à comprendre la différence? Vous devez comprendre que la représentation interne et ce qui est imprimé ne sont pas du tout les mêmes. Quoi qu'il en soit, lisez un peu sur les types de données dans les langages informatiques.
Roland

Dans la colonne "Connexes" à droite se trouve cette question: stackoverflow.com/questions/8804779/…
Matthew Lundberg

1
Essayez x <- 1; is.integer(x); is.numeric(x)donc x <- 1L; is.integer(x); is.numeric(x)et vous pourrez peut-être voir un peu la différence. Les classes entières sont davantage utilisées pour transmettre des variables à partir de constructions C et également dans les structures R. Cependant, il y a beaucoup plus à cela.
Rich Scriven

@Roland Je n'ai pas pensé aux classes spécifiant la précision. J'ai l'habitude d'utiliser des méthodes flottantes pour manipuler des classes entières. Ca a du sens.
Keon

Réponses:


82

Il existe plusieurs classes qui sont regroupées sous forme de classes "numériques", dont les 2 plus courantes sont les doubles (pour les nombres à virgule flottante double précision) et les entiers. R convertira automatiquement entre les classes numériques en cas de besoin, donc dans la plupart des cas, peu importe pour l'utilisateur occasionnel si le nombre 3 est actuellement stocké sous forme d'entier ou de double. La plupart des calculs sont effectués en double précision, c'est donc souvent le stockage par défaut.

Parfois, vous souhaiterez peut-être stocker spécifiquement un vecteur sous forme d'entiers si vous savez qu'ils ne seront jamais convertis en doubles (utilisés comme valeurs d'identification ou d'indexation) car les entiers nécessitent moins d'espace de stockage. Mais s'ils doivent être utilisés dans des mathématiques qui les convertissent en double, alors il sera probablement plus rapide de les stocker simplement en tant que doubles pour commencer.


45

Tout d'abord, il est parfaitement possible d'utiliser R avec succès pendant des années sans avoir besoin de connaître la réponse à cette question. R gère les différences entre les nombres (habituels) et les entiers pour vous en arrière-plan.

> is.numeric(1)

[1] TRUE

> is.integer(1)

[1] FALSE

> is.numeric(1L)

[1] TRUE

> is.integer(1L)

[1] TRUE

(Mettre un 'L' majuscule après un entier oblige à le stocker sous forme d'entier.)

Comme vous pouvez le voir, "integer" est un sous-ensemble de "numeric".

> .Machine$integer.max

[1] 2147483647

> .Machine$double.xmax

[1] 1.797693e+308

Les nombres entiers ne dépassent qu'un peu plus de 2 milliards, tandis que les autres nombres peuvent être beaucoup plus grands. Ils peuvent être plus gros car ils sont stockés sous forme de nombres flottants à double précision. Cela signifie que le nombre est stocké en deux parties: l'exposant (comme 308 ci-dessus, sauf en base 2 plutôt qu'en base 10), et le "significand" (comme 1.797693 ci-dessus).

Notez que «is.integer» n'est pas un test pour savoir si vous avez un nombre entier, mais un test de la façon dont les données sont stockées.

Une chose à surveiller est que l'opérateur deux-points,, :retournera des entiers si les points de début et de fin sont des nombres entiers. Par exemple, 1:5crée un integervecteur de nombres de 1 à 5. Vous n'avez pas besoin d'ajouter la lettre L.

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

Référence: https://www.quora.com/What-is-the-difference-between-numeric-and-integer-in-R


11
Tiré exactement de Quora post N'est-ce pas? Vous auriez pu simplement mentionner la référence!
Srujan Barai


4

Pour citer la page d'aide (essayez ?integer), partie en gras de la mienne:

Les vecteurs entiers existent pour que les données puissent être passées au code C ou Fortran qui les attend, et pour que les (petits) données entières puissent être représentées exactement et de manière compacte .

Notez que les implémentations actuelles de R utilisent des entiers 32 bits pour les vecteurs entiers, de sorte que la plage d'entiers représentables est limitée à environ +/- 2 * 10 ^ 9: les doubles peuvent contenir exactement des entiers beaucoup plus grands.

Comme le dit la page d'aide, les R integersont des nombres signés de 32 bits et peuvent donc contenir entre -2147483648 et +2147483647 et occuper 4 octets.

R numericest identique à un 64 bits doubleconforme à la norme IEEE 754. R n'a pas de type de données de précision unique. (source: pages d'aide de numericet double). Un double peut stocker tous les nombres entiers compris entre -2 ^ 53 et 2 ^ 53 exactement sans perdre en précision.

Nous pouvons voir les tailles des types de données, y compris la surcharge d'un vecteur ( source ):

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

1

À ma connaissance, nous ne déclarons pas de variable avec un type de données, donc par défaut, R a défini un nombre sans L comme un numérique. Si vous avez écrit:

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

Exemple d'entier:

> x<- 2L
> print(x)

Exemple de Numeric (un peu comme double / float d'autres langages de programmation)

> x<-3.4
> print(x)

attention à une plage comme 1:5va créer des entiers.
QWR
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.