Retourner plusieurs objets dans une fonction R [dupliquer]

cette question a déjà une réponse ici:

  • comment affecter à partir d'une fonction qui retourne plus d'une valeur? 12 réponses

Comment retourner plusieurs objets dans une fonction R? En Java, je ferais une classe, peut-être Person qui a quelques variables privées et encapsule, peut-être, height , age , etc.

mais en R, j'ai besoin de passer autour de groupes de données. Par exemple, comment faire pour qu'une fonction R renvoie à la fois une liste de caractères et un entier?

115
demandé sur Hack-R 2012-01-20 06:30:17

6 réponses

contrairement à beaucoup d'autres langues, les fonctions R ne renvoient pas plusieurs objets au sens strict. La façon la plus générale de gérer cela est de retourner un objet list . Donc, si vous avez un entier foo et un vecteur de chaînes de caractères 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 alors accéder à chacun d'eux avec newList$integer ou newList$names .

D'autres types d'objets pourraient mieux fonctionner à diverses fins, mais l'objet list est un bon moyen de commencer.

170
répondu ChadBDot 2012-01-20 02:45:58

de la même manière en Java, vous pouvez créer une classe S4 en R qui encapsule vos informations:

setClass(Class="Person",
         representation(
            height="numeric",
            age="numeric"
          )
)

alors 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
30
répondu RockScience 2016-08-03 01:35:35

est-ce quelque chose dans ce sens 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)
16
répondu aatrujillob 2012-01-20 02:51:19

vous pouvez également utiliser super-assignation.

Plutôt que "<-" type "<<-". La fonction recherchera de façon récursive et répétée un niveau fonctionnel plus haut pour un objet de ce nom. S'il n'en trouve pas, il en créera un au niveau mondial.

4
répondu Daniel Morgan 2014-07-01 13:47:06

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)

à la Recherche des nouveaux objets

ls(pattern = "^r..$")
1
répondu fvfaleiro 2013-08-21 13:30:33

Une façon de gérer cela est de mettre l'information en tant qu'attribut d'une primaire. Je dois souligner, je pense vraiment que c'est la chose à faire seulement lorsque les deux éléments d'information sont liés de sorte que l'un a des informations sur l'autre.

par exemple, je cache parfois le nom de "variables cruciales" ou de variables qui ont été modifiées de manière significative en stockant une liste de noms de variables comme attribut sur la base 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 la base de données elle-même.

1
répondu HoneyBuddha 2016-02-28 02:11:21