Estou aprendendo R e atualmente estou lendo este livro . Para ter certeza de que entendi o conceito, executei o teste a seguir que acabou sendo bastante confuso para mim e agradeceria se você pudesse esclarecê-lo. Aqui está o teste, que eu executei diretamente no shell R do terminal (não usando o RStudio ou o 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
Você poderia me dizer onde está o meu erro e o que eu entendi errado neste problema?
obj_addr(x[1])
duas vezes deve fornecer resultados diferentes, pois cada novo número inteiro terá seu próprio endereço.Respostas:
Qualquer objeto R é um C (ponteiro
SEXP
- chamado - para a) "multi-objeto" (struct
). Isso inclui informações (que o R precisa operar, por exemplolength
, número de referências - para saber quando copiar um objeto - e mais) sobre o objeto R e também os dados reais do objeto R aos quais temos acesso.lobstr::obj_addr
, presumivelmente, retorna o endereço de memória apontadoSEXP
para. Essa parte da memória contém as informações e os dados do objeto R. No ambiente R, não podemos / não precisamos acessar a (ponteiro para) a memória dos dados reais em cada objeto R.Como Adam observa em sua resposta, a função
[
copia o enésimo elemento dos dados contidos no objeto C para um novo objeto C e retorna seuSEXP
ponteiro para R. Cada vez que[
é chamado, um novo objeto C é criado e retornado para R.Não podemos acessar o endereço de memória de cada elemento dos dados reais de nosso objeto por meio de R. Mas, brincando um pouco, podemos rastrear os respectivos endereços usando a api C:
Uma função para obter os endereços:
E aplicando aos nossos dados:
A diferença de memória sucessiva entre os elementos de dados do nosso objeto é igual ao tamanho do
int
tipo:Usando a
[
função:Essa pode ser uma resposta extensa mais do que a necessária e é simplista quanto aos aspectos técnicos reais, mas, esperançosamente, oferece uma imagem "grande" mais clara.
fonte
Esta é uma maneira de olhar para isso. Estou certo de que há uma visão mais técnica. Lembre-se que em R, quase tudo é uma função. Isso inclui a função extrair
[
,. Aqui está uma declaração equivalente ax[1]
:Então, o que você está fazendo é executar uma função que retorna um valor (check-out
?Extract
). Esse valor é um número inteiro. Quando você executaobj_addr(x[1])
, que está avaliando a funçãox[1]
e, em seguida, dando-lhe aobj_addr()
de que o retorno de função, não o endereço do primeiro elemento da matriz que você obrigado a ambosx
ey
.fonte