web-dev-qa-db-fra.com

Qu'est-ce qu'un débordement d'entier dans R et comment cela peut-il se produire?

J'ai des calculs en cours et j'obtiens l'avertissement suivant (c'est-à-dire pas une erreur):

Warning messages:
1: In sum(myvar, na.rm = T) :
Integer overflow - use sum(as.numeric(.))

Dans ce thread les gens déclarent que les débordements d'entiers ne se produisent tout simplement pas. Soit R n'est pas trop moderne, soit ils n'ont pas raison. Cependant, que suis-je censé faire ici? Si j'utilise as.numeric comme l'indique l'avertissement, je ne tiendrais peut-être pas compte du fait que des informations sont perdues bien avant. myvar est lu à partir d'un fichier .csv, donc R ne devrait-il pas comprendre qu'un champ plus grand est nécessaire? Est-ce que cela coupe déjà quelque chose?

Quelle est la longueur maximale de integer ou numeric? Souhaitez-vous suggérer un autre type/mode de champ?

EDIT: je lance:

R version 2.13.2 (2011-09-30) Plate-forme: x86_64-Apple-darwin9.8.0/x86_64 (64 bits) dans R Studio

33
Matt Bannert

Vous pouvez répondre à bon nombre de vos questions en lisant la page d'aide ?integer. Ça dit:

R utilise des entiers 32 bits pour les vecteurs entiers, de sorte que la plage d'entiers représentables est limitée à environ +/- 2 * 10 ^ 9.

L'extension à des entiers plus grands est à l'étude par R Core, mais cela ne se produira pas dans un avenir proche.

Si vous voulez une capacité "bignum", installez paquet Rmpfr [PDF] de Martin Maechler. Je recommande le package 'Rmpfr' en raison de la réputation de son auteur. Martin Maechler est également fortement impliqué dans le développement du package Matrix, ainsi que dans R Core. Il existe des alternatives, notamment des packages arithmétiques tels que les packages 'gmp', 'Brobdingnag' et 'Ryacas' (ce dernier propose également une interface mathématique symbolique).

Ensuite, pour répondre aux commentaires critiques de la réponse à laquelle vous avez lié et comment évaluer la pertinence de votre travail, considérez ceci: s'il y avait la même fonctionnalité statistique disponible dans l'une de ces langues "modernes" que dans R, vous verriez probablement une migration des utilisateurs dans cette direction. Mais je dirais que la migration, et certainement la croissance, vont dans le sens R pour le moment. R a été construit par des statisticiens pour les statistiques.

Il y avait à une époque une variante LISP avec un package de statistiques, Xlisp-Stat, mais son développeur principal et promoteur est maintenant membre de R-Core. D'un autre côté, l'un des premiers développeurs de R, Ross Ihaka, suggère de travailler au développement dans un langage de type LISP [PDF]. Il existe une langue compilée appelée Clojure (prononcée comme les anglophones diraient "fermeture") avec une interface expérimentale, Rincanter.

Mise à jour:

Les nouvelles versions de R (3.0. +) Ont une sorte d'entiers de 53 bits (utilisant la mantisse numeric). Lorsqu'un élément vectoriel "entier" se voit attribuer une valeur supérieure à ".Machine $ integer.max", le vecteur entier est contraint à "numérique", a.k.a. "double". La valeur maximale de integers reste inchangée, cependant, il peut y avoir une coercition de vecteurs entiers pour doubler afin de préserver la précision dans les cas qui généreraient auparavant un débordement. Malheureusement, la longueur des listes, des dimensions de matrice et de tableau et des vecteurs est toujours définie sur integer.max.

Lors de la lecture de grandes valeurs à partir de fichiers, il est probablement plus sûr d'utiliser la classe de caractères comme cible, puis de manipuler. S'il y a une contrainte sur les valeurs NA, il y aura un avertissement.

39
42-

En bref, integer est un type exact avec une plage limitée et numeric est un type à virgule flottante qui peut représenter une plage de valeurs beaucoup plus large mais est inexact. Consultez les pages d'aide (?integer Et ?numeric) Pour plus de détails.

Quant au débordement, voici un explication par Brian D. Ripley:

Cela signifie que vous prenez la moyenne [dans votre cas, la somme - @aix] de très grands nombres entiers, et le calcul déborde. Ce n'est qu'un avertissement.

Cela ne se produira pas dans la prochaine version de R.

Vous pouvez spécifier qu'un nombre est un entier en lui donnant le suffixe L, par exemple, 1L Est l'entier, par opposition à 1 Qui est un virgule flottante , avec la classe "numeric".

Le plus grand entier que vous pouvez créer sur votre machine est donné par .Machine$integer.max.

> .Machine$integer.max
[1] 2147483647
> class(.Machine$integer.max)
[1] "integer"

L'ajout d'un entier positif à cela provoque un débordement, renvoyant NA.

> .Machine$integer.max + 1L
[1] NA
Warning message:
In .Machine$integer.max + 1L : NAs produced by integer overflow
> class(.Machine$integer.max + 1L)
[1] "integer"

Vous pouvez contourner cette limite en ajoutant des valeurs à virgule flottante à la place.

> .Machine$integer.max + 1
[1] 2147483648
> class(.Machine$integer.max + 1)
[1] "numeric"

Étant donné que dans votre cas, l'avertissement est émis par sum, cela indique que le débordement se produit lorsque les nombres sont additionnés. La solution de contournement suggérée sum(as.numeric(.)) devrait faire l'affaire.

21
NPE

Quelle est la longueur maximale d'un entier ou d'un numérique?

Les vecteurs sont actuellement indexés avec un entier, donc la longueur maximale est donnée par .Machine$integer.max. Comme l'a noté DWin, toutes les versions de R utilisent actuellement des entiers 32 bits, ce sera donc 2^31 - 1, soit un peu plus de 2 milliards.

À moins que vous n'emballiez du matériel sérieux (ou que vous lisiez ceci à l'avenir; bonjour de 2012), vous n'aurez pas assez de mémoire pour allouer des vecteurs aussi longtemps.

Je me souviens d'une discussion où R-core (Brian Ripley, je pense) a suggéré que la prochaine étape pourrait être d'indexer les vecteurs avec la mantisse des doubles, ou quelque chose d'intelligent comme ça, donnant effectivement 48 bits d'index. Malheureusement, je ne trouve pas cette discussion.


En plus du package Rmpfr, si vous souffrez d'un dépassement d'entier, vous pouvez essayer le int64 paquet.

4
Richie Cotton