Comment puis-je retourner plusieurs objets dans une fonction R? En Java, je ferais une classe, peut-être Person
qui contient des variables privées et encapsule, peut-être height
, age
, etc.
Mais dans R, je dois passer des groupes de données. Par exemple, comment puis-je faire en sorte qu'une fonction R renvoie à la fois une liste de caractères et un entier?
Contrairement à beaucoup d'autres langages, les fonctions R ne renvoient pas plusieurs objets au sens strict. La méthode la plus générale consiste à renvoyer un objet list
. Donc, si vous avez un entier foo
et un vecteur de chaînes bar
dans votre fonction, vous pouvez créer une liste qui combine ces éléments:
foo <- 12
bar <- c("a", "b", "e")
newList <- list("integer" = foo, "names" = bar)
Puis return
cette liste.
Après avoir appelé votre fonction, vous pouvez accéder à chacune d’elles avec newList$integer
ou newList$names
.
D'autres types d'objets pourraient mieux fonctionner à diverses fins, mais l'objet list
constitue un bon moyen de commencer.
De même en Java, vous pouvez créer une classe S4 dans R qui encapsule vos informations:
setClass(Class="Person",
representation(
height="numeric",
age="numeric"
)
)
Ensuite, votre fonction peut retourner une instance de cette classe:
myFunction = function(age=28, height=176){
return(new("Person",
age=age,
height=height))
}
et vous pouvez accéder à vos informations:
aPerson = myFunction()
aPerson@age
aPerson@height
Est-ce que quelque chose dans ce sens est ce que vous recherchez?
x1 = function(x){
mu = mean(x)
l1 = list(s1=table(x),std=sd(x))
return(list(l1,mu))
}
library(Ecdat)
data(Fair)
x1(Fair$age)
Vous pouvez également utiliser la super-affectation.
Plutôt que "<-", tapez "<< -". La fonction recherchera de manière récurrente et répétée un niveau fonctionnel supérieur pour un objet de ce nom. S'il ne parvient pas à en trouver un, il en créera un au niveau mondial.
Vous pouvez utiliser for()
avec assign()
pour créer de nombreux objets. Voir l'exemple de assign()
:
for(i in 1:6) { #-- Create objects 'r.1', 'r.2', ... 'r.6' --
nam <- paste("r", i, sep = ".")
assign(nam, 1:i)
Regarder les nouveaux objets
ls(pattern = "^r..$")
Une façon de gérer cela consiste à placer les informations en tant qu'attributs sur le principal. Je dois vraiment souligner que j'estime que c'est la bonne chose à faire uniquement lorsque les deux informations sont liées, de sorte que l'une d'entre elles possède des informations sur l'autre.
Par exemple, je cache parfois le nom de "variables cruciales" ou de variables qui ont été modifiées de façon significative en stockant une liste de noms de variables en tant qu'attribut dans le bloc de données:
attr(my.DF, 'Modified.Variables') <- DVs.For.Analysis$Names.of.Modified.Vars
return(my.DF)
Cela me permet de stocker une liste de noms de variables avec le bloc de données lui-même.