2012-01-20 17 views
103

¿Cómo puedo devolver múltiples objetos en una función R? En Java, me gustaría hacer una clase, tal vez Person que tiene algunas variables privadas y encapsula, tal vez, height, age, etc.Devolución de varios objetos en una función R

Pero en I, necesito pasar alrededor de grupos de datos. Por ejemplo, ¿cómo puedo hacer que una función R devuelva una lista de caracteres y un número entero?

+5

Creo que quizás no sea intuitivo para gente que viene de otros idiomas, pero las listas son la manera de hacerlo. Entonces tendrías una lista que contiene dos elementos: una lista y un entero único. – joran

+9

Esta pregunta es muy similar a [este] (http://stackoverflow.com/questions/1826519/function-returning-more-than-one-value). Hay algunas respuestas diferentes por allí. – rakensi

Respuesta

150

A diferencia de muchos otros lenguajes, las funciones R no devuelven múltiples objetos en sentido estricto. La forma más general de manejar esto es devolver un objeto list. Así que si usted tiene un entero foo y un vector de cadenas bar en su función, puede crear una lista que combina estos elementos:

foo <- 12 
bar <- c("a", "b", "e") 
newList <- list("integer" = foo, "names" = bar) 

Entonces return esta lista.

Después de llamar a su función, puede acceder a cada uno de estos con newList$integer o newList$names.

Es posible que otros tipos de objetos funcionen mejor para diversos fines, pero el objeto list es una buena manera de comenzar.

+2

Para asignar los elementos en la lista devuelta a la vez, mira: http://stackoverflow.com/a/15140507 – papirrin

15

¿Es algo en esta línea lo que está buscando?

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) 
29

Del mismo modo, en Java, se puede crear una clase S4 en R que encapsula su información:

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

Luego, su función puede devolver una instancia de esta clase:

myFunction = function(age=28, height=176){ 
    return(new("Person", 
      age=age, 
      height=height)) 
} 

y puede acceder a su información:

aPerson = myFunction() 

[email protected] 
[email protected] 
+0

Acabo de aprender aquí ... ¿cuándo sería útil devolver algo como 'aPerson @ age' o' aPerson @ height' cuando obviamente ya ha definido la edad y la altura con 'myFunction = function (age = 28, height = 176) {...'. Simplemente no lo entiendo (es decir, por qué esto es útil). Entonces has creado una instancia de tu clase, y luego quieres saber detalles sobre la instancia. Pero ya que has instanciado la clase, ¿no sabes ya estos detalles? – warship

+0

@warship es solo un ejemplo ficticio para explicar cómo devolver un objeto. La forma en que construyo el objeto no importa aquí. También podríamos tener myFunction computando la edad y la altura de otros parámetros. – RockScience

+0

Bien, muchas gracias. Solo estoy tratando de aprender un poco más sobre cómo hacer OOP en R (S3, S4, etc.) y cuándo sería útil. – warship

1

Puede usar for() con assign() para crear muchos objetos. Vea el ejemplo de assign():

for(i in 1:6) { #-- Create objects 'r.1', 'r.2', ... 'r.6' -- 
    nam <- paste("r", i, sep = ".") 
    assign(nam, 1:i) 

Mirando los nuevos objetos

ls(pattern = "^r..$") 
4

También puede utilizar super-asignación.

En lugar de "< -" tipo "< < -". La función buscará recursiva y repetidamente un nivel funcional más alto para un objeto de ese nombre. Si no puede encontrar uno, creará uno en el nivel global.

1

Una forma de manejar esto es colocar la información como un atributo en la primaria. Debo enfatizar, realmente creo que esto es lo apropiado para hacer solo cuando las dos piezas de información están relacionadas de tal manera que uno tiene información sobre el otro.

Por ejemplo, a veces esconder el nombre de "variables cruciales" o variables que se han modificado de manera significativa mediante el almacenamiento de una lista de nombres de variables como un atributo de la trama de datos:

attr(my.DF, 'Modified.Variables') <- DVs.For.Analysis$Names.of.Modified.Vars 
return(my.DF) 

Esto me permite almacenar una lista de nombres de variables con el propio marco de datos.

Cuestiones relacionadas