web-dev-qa-db-fra.com

Pourquoi les indices vectoriels dans R commencent-ils par 1 au lieu de 0?

Quelle est la raison pour laquelle les index de vecteur dans R commencent par 1, au lieu du 0 habituel?

Exemple:

> arr<-c(10,20)
> arr[0]
numeric(0)
> arr[1]
[1] 10
> arr[2]
[1] 20

Est-ce juste qu'ils veulent stocker des informations supplémentaires sur le vecteur et ne savent pas où les stocker sauf en tant que premier élément du vecteur?

26
Frank

FORTRAN est un langage qui commence les tableaux à 1. Les mathématiciens traitent des vecteurs qui commencent toujours par le composant 1 et passent par N. Les conventions d'algèbre linéaire commencent par les lignes et les colonnes numérotées 1 et passent également par N.

C a commencé par zéro en raison de l'arithmétique de pointeur implicite sous-jacente. Java, JavaScript, C++ et C # ont emboîté le pas à C.

41
duffymo

Les vecteurs en mathématiques sont souvent représentés par des n-uplets, dont les éléments sont indexés de 1 à n. Je soupçonne que r voulait rester fidèle à cette notation.

16
Jan Gorzny

Frank, je pense que vous avez mal interprété ce que vous avez vu lorsque vous avez tapé arr [0]. Le chiffre (0) signifie simplement que le résultat est un vecteur numérique sans élément. Cela ne signifie pas que le type de vecteur est "stocké" dans l'élément 0. Vous auriez obtenu le même résultat si vous aviez tapé, par exemple, arr [arr> 30]. Aucun élément ne remplit cette condition, le vecteur de résultat ne contient donc aucun élément. De même, aucun élément n'a l'indice 0. C'est intentionnel et n'a rien à voir avec l'espace 0 utilisé pour autre chose. 

9
goodside

0 est seulement "habituel" parce que c'est ce que C a fait, et beaucoup de langages ultérieurs ont copié la syntaxe C de manière esclave. Par défaut dans Fortran, les tableaux sont basés sur 1. 

Dans Ada, il n'y a pas de valeur par défaut et vous devez choisir les plages de début et de fin. Fait intéressant, il semble que la plupart des codes que j'ai rencontrés aient choisi «1» pour la limite inférieure. Je pense que c'est une assez bonne indication de l'endroit où les gens seraient allés s'ils avaient le choix.

8
T.E.D.

R est une "plateforme d'expérimentation et de recherche". Son objectif est de permettre à "des statisticiens d’utiliser toutes les capacités d’un tel environnement" sans repenser la manière dont ils traitent habituellement les statistiques. Les gens utilisent donc des formules pour créer des modèles de régression, et ils commencent à compter à 1.

3
Wok

En fait, je pense que la version du type C qui commence par 0 est très logique quand on regarde la manière dont la mémoire est organisée. En C, on peut écrire ce qui suit:

int* T = new int[10];

Le premier élément du tableau est * T. C'est parfaitement "logique" car * T est l'adresse du premier cas de mémoire pointé. Le second élément est le second cas donc * (T + 1): on avance d'un "sizeof (int)".

Pour rendre le code plus lisible, C a implémenté un alias: T [i] pour * (T + i). Pour accéder au premier élément, vous devez accéder à * T qui est T [0]. C'est parfaitement naturel.

Cette idée est étendue par les itérateurs:

std::vector<int> T(10);
int val = *(T.begin()+3);

T [i] n'est qu'un alias pour * (T.begin () + i).

Dans fortran/R, nous en général commençons par 1 à cause de problèmes mathématiques, mais il existe certainement d’autres bons choix (cf ce lien par exemple). N'oubliez pas que fortran peut facilement utilise un tableau commençant par 0:

PROGRAM ZEROARRAY
REAL T(0:9)
T(0) = 3.14
END
3
ThR37

Vous le faites mal. Si vous souhaitez stocker des attributs supplémentaires dans un objet, utilisez attr:

> foo <- 1:20
> attr(foo, "created") <- Sys.time()               # just as an example
> str(foo)
 atomic [1:20] 1 2 3 4 5 6 7 8 9 10 ...
 - attr(*, "created")= POSIXct[1:1], format: "2010-06-28 14:07:15"    # our time
> summary(foo)                                     # object works as usual
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   1.00    5.75   10.50   10.50   15.20   20.00 
> 
0
Dirk Eddelbuettel