J'apprends R et actuellement je lis ce livre . Pour m'assurer de bien comprendre le concept, j'ai effectué le test suivant qui s'est avéré assez déroutant pour moi et j'apprécierais si vous pouviez le clarifier. Voici le test, que j'ai exécuté directement dans le shell R à partir du terminal (sans utiliser RStudio ou Emacs ESS).
> library(lobstr)
>
> x <- c(1500,2400,8800)
> y <- x
> ### So the following two lines must return the same memory address
> obj_addr(x)
[1] "0xb23bc50"
> obj_addr(y)
[1] "0xb23bc50"
> ### So as I expected, indeed both x and y point to the same memory
> ### location: 0xb23bc50
>
>
>
> ### Now let's check that each element can be referenced by the same
> ### memory address either by using x or y
> x[1]
[1] 1500
> y[1]
[1] 1500
> obj_addr(x[1])
[1] "0xc194858"
> obj_addr(y[1])
[1] "0xc17db88"
> ### And here is exactly what I don't understand: x and y point
> ### to the same memory address, so the same must be true for
> ### x[1] and y[1]. So how come I obtain two different memory
> ### addresses for the same element of the same vector?
>
>
>
> x[2]
[1] 2400
> y[2]
[1] 2400
> obj_addr(x[2])
[1] "0xc15eca0"
> obj_addr(y[2])
[1] "0xc145d30"
> ### Same problem!
>
>
>
> x[3]
[1] 8800
> y[3]
[1] 8800
> obj_addr(x[3])
[1] "0xc10e9b0"
> obj_addr(y[3])
[1] "0xc0f78e8"
> ### Again the same problem: different memory addresses
Pourriez-vous me dire où est mon erreur et ce que j'ai mal compris dans ce problème?
obj_addr(x[1])
deux fois devrait vous donner des résultats différents, car chaque nouvel entier aura sa propre adresse.Réponses:
Tout objet R est un C (pointeur -appelé
SEXP
- vers a) "multi-objet" (struct
). Cela inclut des informations (que R doit exploiter, par exemplelength
, le nombre de références - pour savoir quand copier un objet - et plus) sur l'objet R et, également, les données réelles de l'objet R auxquelles nous avons accès.lobstr::obj_addr
, vraisemblablement, renvoie l'adresse mémoire vers laquelleSEXP
pointe un . Cette partie de la mémoire contient à la fois les informations et les données de l'objet R. Depuis l'environnement R, nous ne pouvons / n'avons pas besoin d'accéder à la (pointeur vers) la mémoire des données réelles de chaque objet R.Comme Adam le note dans sa réponse, la fonction
[
copie le nième élément des données contenues dans l'objet C dans un nouvel objet C et renvoie sonSEXP
pointeur sur R. À chaque[
appel, un nouvel objet C est créé et renvoyé à R.Nous ne pouvons pas accéder à l'adresse mémoire de chaque élément des données réelles de notre objet via R. Mais en jouant un peu, nous pouvons tracer les adresses respectives à l'aide de l'API C:
Une fonction pour obtenir les adresses:
Et en appliquant à nos données:
La différence de mémoire successive entre les éléments de données de notre objet est égale à la taille du
int
type:Utilisation de la
[
fonction:Cela pourrait être une réponse approfondie plus que nécessaire et simpliste sur les aspects techniques réels, mais, espérons-le, offre une "vue d'ensemble" plus claire.
la source
C'est une façon de voir les choses. Je suis sûr qu'il y a une vision plus technique. N'oubliez pas qu'en R, presque tout est fonction. Cela inclut la fonction d'extraction,
[
. Voici une déclaration équivalente àx[1]
:Donc, ce que vous faites, c'est exécuter une fonction qui retourne une valeur (check out
?Extract
). Cette valeur est un entier. Lorsque vous exécutezobj_addr(x[1])
, il évalue la fonctionx[1]
et vous donne ensuite leobj_addr()
retour de cette fonction, pas l'adresse du premier élément du tableau que vous avez lié aux deuxx
ety
.la source