2012-01-20 13 views
103

Jak mogę zwrócić wiele obiektów w funkcji R? W Javie, chciałbym zrobić lekcje, może Person który ma kilka zmiennych prywatnych i hermetyzuje, być może, height, age itpPowracanie wielu obiektów w funkcji R

Ale w R, muszę przechodzić wokół grupy danych. Na przykład, w jaki sposób mogę utworzyć funkcję R, zwracając zarówno listę znaków, jak i liczbę całkowitą?

+5

Myślę, że może nie jest to intuicyjne dla osób pochodzących z innych języków, ale listy są sposobem na zrobienie tego. Więc będziesz miał listę zawierającą dwa elementy: listę i jedną liczbę całkowitą. – joran

+9

To pytanie jest bardzo podobne do [this] (http://stackoverflow.com/questions/1826519/function-returning-more-than-one-value). Istnieje wiele różnych odpowiedzi. – rakensi

Odpowiedz

150

W przeciwieństwie do wielu innych języków, funkcje R nie zwracają wielu obiektów w ścisłym tego słowa znaczeniu. Najbardziej ogólnym sposobem na obsłużenie tego jest zwrócenie obiektu list. Więc jeśli masz całkowitą foo oraz wektor ciągów bar w swojej funkcji, można utworzyć listę, która łączy te elementy:

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

Następnie return tej listy.

Po wywołaniu funkcji można uzyskać dostęp do każdej z nich za pomocą newList$integer lub newList$names.

Inne typy obiektów mogą lepiej działać w różnych celach, ale obiekt list jest dobrym sposobem na rozpoczęcie pracy.

+2

Aby przypisać elementy na zwróconej liście naraz, spójrz na: http://stackoverflow.com/a/15140507 – papirrin

15

Czy szukasz czegoś podobnego?

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

Podobnie w Javie, można utworzyć klasę S4 w R, która zamyka swoje informacje:

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

Wtedy twoja funkcja może zwracać instancję tej klasy:

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

i możesz uzyskać dostęp do swoich informacji:

aPerson = myFunction() 

[email protected] 
[email protected] 
+0

Po prostu uczenie się tutaj ... kiedy byłoby użyteczne zwrócenie czegoś w stylu 'aPerson @ age' lub' aPerson @ height', gdy oczywiście już zdefiniowałeś wiek i wysokość za pomocą funkcji 'myFunction = (wiek = 28, wysokość = 176) {...'. Po prostu tego nie rozumiem (tzn. Dlaczego jest to przydatne). Utworzono więc swoją klasę, a następnie chcesz poznać szczegóły dotyczące instancji. Ale odkąd stworzyłeś klasę, nie znasz już tych szczegółów? – warship

+0

@warship to po prostu fałszywy przykład wyjaśniający, jak zwrócić obiekt. Sposób, w jaki buduję obiekt, nie ma tutaj znaczenia. Moglibyśmy również obliczyć, że moja funkcja oblicza wiek i wysokość na podstawie innych parametrów. – RockScience

+0

Okay, wielkie dzięki. Po prostu próbuję dowiedzieć się trochę więcej o robieniu OOP w R (S3, S4 itd.) I kiedy byłoby to przydatne. – warship

1

Można użyć for() z assign(), aby utworzyć wiele obiektów. Patrz przykład z assign():

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

szuka nowych obiektów

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

Można również użyć super-zadanie.

Zamiast "< -" wpisz "< < -". Funkcja będzie rekurencyjnie i wielokrotnie przeszukiwać jeden poziom funkcjonalny wyżej dla obiektu o tej nazwie. Jeśli go nie znajdzie, stworzy jeden na poziomie globalnym.

1

Jednym ze sposobów rozwiązania tego problemu jest umieszczenie informacji jako atrybutu na pierwotnym. Muszę podkreślić, naprawdę uważam, że jest to właściwe, aby robić to tylko wtedy, gdy te dwie informacje są powiązane tak, że jedna ma informacje na temat drugiej.

Na przykład, czasami ukryta pod nazwą „kluczowych zmiennych” lub zmiennych, które zostały znacznie zmodyfikowany poprzez przechowywanie listy nazw zmiennych jako atrybut na ramce danych:

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

To pozwala mi zapisz listę nazw zmiennych z samą ramką danych.