Menu

Les nombres en R : numeric, integer et fonctions mathématiques

Travailler avec les nombres en R : numeric ou integer, la famille des arrondis, sqrt et log, l'opérateur modulo %%, et les valeurs spéciales Inf et NaN.

Cette page contient des éditeurs exécutables - modifiez, exécutez et voyez la sortie instantanément.

Numeric et integer : les deux types de nombres de R

R stocke les nombres de deux façons. Numeric (stocké comme un flottant double précision) est le type par défaut - chaque nombre que tu tapes est un double, sauf indication contraire. Integer est un type d'entier exact distinct, que tu demandes avec le suffixe L :

En pratique tu n'as presque jamais à t'en soucier : R convertit silencieusement entre les deux, et is.numeric() vaut TRUE pour les deux (voir les types de données pour le système de types complet). Le seul endroit où la distinction se voit, c'est la division - / renvoie toujours un double, même entre deux entiers :

Les entiers apparaissent surtout en sortie des fonctions de comptage (length(), seq_len(), nrow()) et comme valeurs d'indice. Quand tu as besoin d'une division entière, R a un opérateur dédié - traité plus bas.

La famille des arrondis

R te donne cinq façons de rogner un nombre, chacune avec un sens distinct :

  • round(x, digits) - à un nombre de décimales (0 par défaut).
  • floor(x) - vers le bas jusqu'à l'entier le plus proche, toujours vers moins l'infini.
  • ceiling(x) - vers le haut, toujours vers plus l'infini.
  • trunc(x) - coupe les décimales, toujours vers zéro. Note la différence sur les négatifs : trunc(-2.7) vaut -2, mais floor(-2.7) vaut -3.
  • signif(x, digits) - à un nombre de chiffres significatifs, pas de décimales : signif(123456, 2) vaut 120000.

Et une surprise célèbre : round() utilise l'arrondi au pair le plus proche (arrondi du banquier) sur les demis exacts, conformément à la norme IEEE 754 :

Ça affiche 0 2 2 4 - chaque demi est arrondi vers le nombre pair le plus proche. Ce n'est pas un bug ; ça évite un biais systématique vers le haut quand tu sommes beaucoup de valeurs arrondies. Si un rapport a besoin de l'arrondi scolaire, ajoute un tout petit décalage ou formate à la couche de présentation.

Les fonctions mathématiques du quotidien

Les bases marchent exactement comme tu l'imagines :

sqrt() est la racine carrée, abs() la valeur absolue, ^ l'exponentiation, et exp(x) c'est e puissance x - donc exp(1) est le nombre d'Euler, environ 2,718282.

La fonction qui fait trébucher tout le monde, c'est log(). En R, log() est le logarithme naturel (base e), pas le logarithme en base 10 :

La première ligne affiche à peu près 4.60517 - pas le 2 qu'attend un lecteur habitué à la base 10. Passe par log10() et log2() quand tu veux ces bases, ou fournis base = explicitement. (Cette convention est standard en statistique, où le logarithme naturel est le choix par défaut.)

Modulo %% et division entière %/%

Deux opérateurs couvrent l'arithmétique du reste :

%% est le modulo (le reste) : 17 divisé par 5 fait 3 reste 2. %/% est la division entière : combien de 5 entiers tiennent dans 17. Ensemble ils vérifient x == (x %/% y) * y + (x %% y).

L'usage classique de %% est le test de divisibilité :

Une subtilité avec les nombres négatifs : le %% de R prend le signe du diviseur (comme Python, contrairement à C) :

C'est 2, pas -1 - R répond « qu'est-ce que j'ajoute à un multiple de 3 pour atteindre -7 ? », ce qui garde les résultats dans 0..2 pour un diviseur positif. Pratique pour faire boucler des indices ; surprenant si tu viens de C ou de Java.

Valeurs spéciales : Inf, -Inf et NaN

Les nombres de R suivent la norme IEEE 754, donc certaines opérations produisent des valeurs spéciales plutôt que des erreurs :

1/0 donne Inf (l'infini), -1/0 donne -Inf, et 0/0 - une quantité réellement indéfinie - donne NaN, « not a number ». La distinction compte : Inf est une réponse (« plus grand que tout »), NaN est l'absence de réponse. Tu les testes avec des fonctions dédiées, parce que == NaN ne marche jamais :

Note la dernière ligne : NaN compte aussi comme NA, donc is.na() l'attrape - une raison de plus pour laquelle is.na() est le test standard « cette valeur est-elle inutilisable ? » (plus de détails dans les valeurs manquantes).

R lit et écrit aussi la notation scientifique nativement - 2.5e3 vaut 2500, et les nombres très petits ou très grands s'affichent en notation e par défaut :

Utilise format(x, scientific = FALSE) (ou l'option scipen) quand un rapport a besoin de décimaux en clair.

La surprise de la virgule flottante

Tous les langages qui stockent les décimaux en binaire partagent celle-ci, et R ne fait pas exception :

FALSE - parce que 0.1 + 0.2 vaut en réalité 0.30000000000000004. Ni 0,1 ni 0,2 n'ont de représentation binaire exacte, et les minuscules erreurs s'accumulent. L'affichage par défaut de R masque ça en montrant 7 chiffres significatifs, c'est pourquoi le problème semble invisible jusqu'à ce qu'une comparaison == échoue.

La règle : ne compare jamais des décimaux calculés avec ==. Utilise all.equal(), qui compare à une tolérance raisonnable :

Enveloppe-le dans isTRUE() parce que all.equal() renvoie une description de la différence (et non FALSE) quand les valeurs diffèrent. Pour du travail sur des entiers où l'exactitude compte, les integers sont exacts jusqu'à environ 2,1 milliards - une raison de plus pour laquelle le code de comptage utilise le type integer.

Ce que tu retiens

  • Tout nombre tapé est un double ; 42L crée un integer, et / renvoie un double dans tous les cas.
  • round() arrondit au pair le plus proche ; floor/ceiling/trunc/signif rognent chacun différemment - sache lequel tu veux.
  • log() est le logarithme naturel ; utilise log10(), log2() ou base = pour les autres bases.
  • %% donne le reste (le signe suit le diviseur), %/% le quotient entier.
  • 1/0 vaut Inf, 0/0 vaut NaN, et 0.1 + 0.2 != 0.3 - compare les décimaux avec all.equal(), jamais avec ==.

Prochaine étape : l'autre moitié des données du quotidien - les chaînes de caractères, et les fonctions que R te donne pour les construire, les formater et les fouiller.

Questions fréquentes

Quelle est la différence entre numeric et integer en R ?

Numeric (double) est le type par défaut de R pour tout nombre que tu tapes - 42 est un double même s'il a l'air entier. Integer est un type de stockage distinct que tu demandes avec le suffixe L : 42L. La division classique renvoie toujours un double, même entre entiers ; utilise %/% pour la division entière.

log() en R est-il le logarithme naturel ?

Oui - log(x) en R est le logarithme naturel (base e), pas le logarithme en base 10. Utilise log10() pour la base 10, log2() pour la base 2, ou log(x, base = b) pour n'importe quelle base. log(100) vaut environ 4,605, pas 2.

Comment fonctionne round() en R ?

round(x, digits) arrondit au nombre de décimales indiqué, mais les demis exacts utilisent l'« arrondi au pair le plus proche » (arrondi du banquier) : round(2.5) vaut 2 et round(3.5) vaut 4. Cela suit la norme IEEE 754 et réduit le biais lorsqu'on somme des valeurs arrondies, mais ça surprend ceux qui attendent l'arrondi scolaire.

Pourquoi 0.1 + 0.2 n'est-il pas égal à 0.3 en R ?

Les doubles sont stockés en binaire, et 0,1, 0,2 et 0,3 n'ont pas de représentation binaire exacte, donc 0.1 + 0.2 vaut en réalité 0,30000000000000004. Ne compare jamais des décimaux calculés avec == ; utilise isTRUE(all.equal(x, y)) ou vérifie abs(x - y) < 1e-9.

Coddy programming languages illustration

Apprendre à coder avec Coddy

COMMENCER