web-dev-qa-db-fra.com

Renvoi de plusieurs objets dans une fonction R

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?

125
CodeGuy

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.

191
ChadBDot

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
35
RockScience

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)
18
aatrujillob

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.

5
Daniel Morgan

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..$")
2
fvfaleiro

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.

1
HoneyBuddha