2016-05-16 92 views
2

函數A中,函數B從函數A的環境中獲取4個對象並對其進行修改。然後,我需要將這些對象發送回函數A的環境。R:函數內的函數:管理環境

我在尋找最佳實踐建議: 當前我所做的是:函數B返回一個包含該對象的列表,並且每個對象都將被覆蓋函數A的環境是否有更好的處理方法? 有關管理環境的討論非常複雜,對於社區來說這是一個重要且簡單的問題。

下面是我實現的一些僞代碼

Function A = getObjects(A,B,C){ 

A= A+1 
B= B+1 
C= C+1 

# Function B returns a list containing the object after certain operations were # performed on these 

listFromFunctionB = FunctionB(A,B,C) 

A = listFromFunctionB$A 
B = listFromFunctionB$B 
C = listFromFunctionB$C 

#Other operations keep going on objects A,B and C 
} 
+0

如果這些對象永遠一起走將它們保存在列表中可能更有意義 - 甚至可以爲它們中的三個創建一個S3類。 – Gregor

+0

請問你能更具體嗎? – Fredkho

+0

我已經添加了答案。我不認爲我能比你更具體地瞭解你正在做的事情的類型。但是tl; dr會將它們保存在一個列表中,並使用'lapply' *而不是將它們從列表中移出並在每一步中重新放入。 – Gregor

回答

2

也許沒有更好的做法比你已經得到了。功能編程語言(如R)通常不允許函數修改輸入參數。

此外,R函數只返回一個對象,所以返回包含對象A,B和C的列表也是正確的方法。

+0

在同一個環境中設置這兩個函數怎麼樣? 我在大多數情況下並不推薦它,但是在上面會避免處理這個列表和輸出 – Fredkho

+0

正如@tony所說,通過列表絕對是推薦的方法。這不是唯一的方法。可以使用<< - 或assign()函數在函數內改變父範圍中的值,但這通常是不好的做法,容易導致意想不到的副作用。我強烈建議你接受你在這個答案中的建議,並堅持使用列表從函數返回多個值,這是最好的方法。引用R地獄。「如果你認爲你需要」 - ,再想一想,如果反思,你仍然認爲你需要「 - ,再想一想」。 – dww

0

從你的玩具例子中很難分辨出來,但看起來你有三個對象A,B和C,它們都是一起操作並一起傳遞的。在每一步中,你將它們從列表中取出,對它們中的每一個做一些事情,並將它們放回列表中,以便它們可以作爲一個函數返回。

一般來說,這很好。您不能返回多個對象,因此您需要將它們返回到列表中。每次浪費都會從列表中排除。何必?

事實上,對lapply這個列表中的每個項目做同樣的事情是很容易的。您的代碼使您看起來像是複製/粘貼行,並將A更改爲B,然後更改爲C。良好的編程應該涉及很少的複製/粘貼。

而不是編寫A, B, C的函數,編寫期望list(A, B, C)作爲輸入的函數。

你有做一些是增加一個爲A,B和C.這裏是你會怎麼做,如果他們是在一個列表中唯一的例子:

FunctionA = function(ABClist) { 
    # add 1 to each list element 
    return(lapply(ABClist, function(x) x + 1)) 
}