2012-01-20 42 views
103

Làm cách nào để trả về nhiều đối tượng trong một hàm R? Trong Java, tôi sẽ làm cho một lớp, có lẽ Person trong đó có một số biến tư nhân và đóng gói, có thể, height, age vvTrả về nhiều đối tượng trong một hàm R

Nhưng trong R, tôi cần phải vượt qua xung quanh các nhóm dữ liệu. Ví dụ, làm thế nào tôi có thể làm cho một hàm R trả về cả một danh sách các ký tự và một số nguyên?

+5

Tôi nghĩ có lẽ nó không trực quan với những người đến từ các ngôn ngữ khác, nhưng danh sách là cách để làm điều này. Vì vậy, bạn sẽ có một danh sách có chứa hai yếu tố: một danh sách và một số nguyên duy nhất. – joran

+9

Câu hỏi này rất giống với câu hỏi này [http://stackoverflow.com/questions/1826519/function-returning-more-than-one-value). Có một số câu trả lời khác nhau ở đó. – rakensi

Trả lời

150

Không giống như nhiều ngôn ngữ khác, chức năng R không trả về nhiều đối tượng theo nghĩa hẹp. Cách tổng quát nhất để xử lý việc này là trả về một đối tượng list. Vì vậy, nếu bạn có một số nguyên foo và một vector của chuỗi bar trong chức năng của bạn, bạn có thể tạo một danh sách kết hợp các mặt hàng này:

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

Sau đó return danh sách này.

Sau khi gọi chức năng của bạn, bạn có thể truy cập từng chức năng này với newList$integer hoặc newList$names.

Các loại đối tượng khác có thể hoạt động tốt hơn cho nhiều mục đích khác nhau, nhưng đối tượng list là một cách hay để bắt đầu.

+2

Để chỉ định các phần tử trong danh sách trả lại cùng một lúc, hãy xem: http://stackoverflow.com/a/15140507 – papirrin

15

Có gì đó nằm dọc theo những dòng bạn đang tìm kiếm không?

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

Tương tự như vậy trong Java, bạn có thể tạo ra một lớp S4 R mà gói gọn thông tin của bạn:

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

Sau đó, chức năng của bạn có thể trở lại một thể hiện của lớp này:

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

và bạn có thể truy cập thông tin của mình:

aPerson = myFunction() 

[email protected] 
[email protected] 
+0

Chỉ cần tìm hiểu ở đây ... khi nào sẽ hữu ích khi trả lại nội dung nào đó như 'aPerson @ age' hoặc' aPerson @ height' khi bạn rõ ràng đã xác định tuổi và chiều cao với hàm 'myFunction = (tuổi = 28, chiều cao = 176) {...'. Tôi chỉ không hiểu nó (tức là, tại sao điều này hữu ích). Vì vậy, bạn đã khởi tạo lớp của bạn, và sau đó bạn muốn biết chi tiết về cá thể. Nhưng vì bạn đã khởi tạo lớp học, bạn có biết những chi tiết này không? – warship

+0

@warship nó chỉ là một ví dụ giả để giải thích cách trả về một đối tượng. Cách tôi xây dựng đối tượng không quan trọng ở đây. Chúng tôi cũng có thể có myFunction tính tuổi và chiều cao từ các thông số khác. – RockScience

+0

Được rồi, cảm ơn rất nhiều. Tôi chỉ cố gắng tìm hiểu thêm một chút về việc thực hiện OOP trong R (S3, S4, vv), và khi nào nó sẽ hữu ích. – warship

1

Bạn có thể sử dụng for() với assign() để tạo nhiều đối tượng. Xem ví dụ từ assign():

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

Nhìn các đối tượng mới

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

Bạn cũng có thể sử dụng siêu chuyển nhượng.

Thay vì "< -" hãy nhập "< < -". Hàm sẽ đệ quy và liên tục tìm kiếm một mức chức năng cao hơn cho một đối tượng của tên đó. Nếu nó không thể tìm thấy nó, nó sẽ tạo ra một cái ở cấp độ toàn cầu.

1

Một cách để xử lý việc này là đặt thông tin dưới dạng thuộc tính trên danh sách chính. Tôi phải căng thẳng, tôi thực sự nghĩ rằng đây là điều thích hợp để làm chỉ khi hai mẩu thông tin liên quan đến nhau mà người ta có thông tin về người kia.

Ví dụ, đôi khi tôi giấu tên của "biến quan trọng" hoặc các biến đã được sửa đổi đáng kể bằng cách lưu trữ một danh sách các tên biến như một thuộc tính vào khung dữ liệu:

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

này cho phép tôi lưu trữ danh sách các tên biến với chính khung dữ liệu.

Các vấn đề liên quan