70 votes

Passe par référence

Pouvez-vous passer par référence avec "R"? par exemple, dans le code suivant:

 setClass("MyClass",
    representation(
    name="character"
    ))


instance1 <-new("MyClass",name="Hello1")
instance2 <-new("MyClass",name="Hello2")

array = c(instance1,instance2)

instance1
array

instance1@name="World!"

instance1
array
 

la sortie est

 > instance1
An object of class "MyClass"
Slot "name":
[1] "World!"

> array
[[1]]
An object of class "MyClass"
Slot "name":
[1] "Hello1"


[[2]]
An object of class "MyClass"
Slot "name":
[1] "Hello2"
 

mais j'aimerais que ce soit

 > instance1
An object of class "MyClass"
Slot "name":
[1] "World!"

> array
[[1]]
An object of class "MyClass"
Slot "name":
[1] "World!"


[[2]]
An object of class "MyClass"
Slot "name":
[1] "Hello2"
 

c'est possible ?

Merci

Pierre

56voto

doug Points 29567

Pas de.

Les objets dans les instructions d'affectation sont immuables. R copie de l'objet n'est pas seulement la référence.

> v = matrix(1:12, nrow=4)
> v
           [,1] [,2] [,3]
     [1,]    1    5    9
     [2,]    2    6   10
     [3,]    3    7   11
     [4,]    4    8   12
> v1 = v
> v1[,1]     # fetch the first column 
     [1] 1 2 3 4

(condition: la déclaration ci-dessus est vraie pour R primitives, par exemple, vecteurs, matrices), et aussi pour les fonctions; je ne peux pas dire avec certitude si c'est vrai pour tous les objets R--que la plupart d'entre eux, ainsi que la grande majorité de celles qui sont le plus souvent utilisés.)

Si vous n'aimez pas ce comportement, vous pouvez vous désinscrire à l'aide d'un Package R. E. g., il y a un Package R appelé R. oo qui permet d'imiter les passer par référence en comportement; R. oo est disponible sur CRAN.

48voto

Ari B. Friedman Points 24940

Notez que si vous souhaitez utiliser la méthode de référence par référence simplement pour éviter les conséquences sur les performances de la copie d'un objet non modifié (comme c'est le cas dans d'autres langues à références constantes), R effectue automatiquement cette opération:

 n <- 10^7
bigdf <- data.frame( x=runif(n), y=rnorm(n), z=rt(n,5) )
myfunc <- function(dat) invisible(with( dat, x^2+mean(y)+sqrt(exp(z)) ))
myfunc2 <- function(dat) {
    x <- with( dat, x^2+mean(y)+sqrt(exp(z)) )
    invisible(x)
}
myfunc3 <- function(dat) {
    dat[1,1] <- 0
    invisible( with( dat, x^2+mean(y)+sqrt(exp(z)) ) )
}
tracemem(bigdf)
> myfunc(bigdf)
> # nothing copied
> myfunc2(bigdf)
> # nothing copied!
> myfunc3(bigdf)
tracemem[0x6e430228 -> 0x6b75fca0]: myfunc3 
tracemem[0x6b75fca0 -> 0x6e4306f0]: [<-.data.frame [<- myfunc3 
tracemem[0x6e4306f0 -> 0x6e4304f8]: [<-.data.frame [<- myfunc3 
> 
> library(microbenchmark)
> microbenchmark(myfunc(bigdf), myfunc2(bigdf), myfunc3(bigdf), times=5)
Unit: milliseconds
            expr       min        lq    median        uq       max
1 myfunc2(bigdf)  617.8176  641.7673  644.3764  683.6099  698.1078
2 myfunc3(bigdf) 1052.1128 1134.0822 1196.2832 1202.5492 1206.5925
3  myfunc(bigdf)  598.9407  622.9457  627.9598  642.2727  654.8786
 

28voto

Rappster Points 2495

Comme plusieurs l'ont déjà indiqué, cela peut être fait en utilisant des objets de la classe environment . Il existe une approche formelle fondée sur l'utilisation de environment s. C'est ce qu'on appelle les classes de référence et rend les choses vraiment faciles pour vous. Vérifiez ?setRefClass pour la page d’aide de l’entrée principale. Il explique également comment utiliser des méthodes formelles avec des classes de référence.

Exemple

 setRefClass("MyClass",
    fields=list(
        name="character"
    )
)

instance1 <- new("MyClass",name="Hello1")
instance2 <- new("MyClass",name="Hello2")

array = c(instance1,instance2)

instance1$name <- "World!"
 

Sortie

 > instance1
Reference class object of class "MyClass"
Field "name":
[1] "World!"

> array
[[1]]
Reference class object of class "MyClass"
Field "name":
[1] "World!"

[[2]]
Reference class object of class "MyClass"
Field "name":
[1] "Hello2"
 

21voto

teucer Points 1877

Passage par référence est possible pour environments. Vous pouvez essayer de les utiliser, en gros, à chaque fois que vous créez un objet, vous devrez créer un environnement de fente aussi bien. Mais je pense que c'est lourd. Avoir un regard sur les Pointeurs et passage par référence dans la R et Passage par référence pour S4.

4voto

Botond Sipos Points 59

En fait, le paquetage R.oo émule le comportement de référence par référence en utilisant des environnements.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X