2015-07-28 24 views
6

Rozważmy następujący kodR: deep copy funkcją argumentu

i = 3 
j = i 
i = 4 # j != i 

Jednak to, co chcę jest

i = 3 
f <- function(x, j=i) 
    x * j 
i = 4 
f(4) # 16, but i want it to be 12 

W przypadku, gdy zastanawiasz się, dlaczego chcesz to zrobić, można rozważyć ten kod - aplikacja jest modelem wielokrotnych dekrementów. Przekątne macierzy przejścia są sumą innych ubytków w tym wierszu. Chciałbym zdefiniować potrzebne mi ubytki, niż wyliczyć inne funkcje przy użyciu tych ubytków. W tym przypadku potrzebuję tylko Uxt01 i Uxt10 iz nich chcę utworzyć funkcje uxt00 i Uxt11. Chciałem czegoś, co skaluje się do wyższych wymiarów.

Qxt <- matrix(c(uxt00=function(t=0,x=0) 0, 
       uxt01=function(t=0,x=0) 0.05, 
       uxt10=function(t=0,x=0) 0.07 
       uxt11=function(t=0,x=0) 0), 2, 2, byrow=TRUE) 

Qxt.diag <- function(Qxt) { 
    ndecrements <- length(Qxt[1,]) 
    for(index in seq(1, N, N+1)) { # 1, 4 
     Qxt[[index]] <- function(t=0, x=0, i=index, N=ndecrements) { 
      row <- ceiling(index/ndecr) 
      row.decrements <- seq((row - 1)*N + 1, (row)*N) 
      other.decrements <- row.decrements[which(row.decrements != i] 
      -sum(unlist(lapply(Qxt.fns[[other.decrements]], 
       function(f) f(t,x)))) 
     } 
    } 
    Qxt.fns 
} 
+0

Czy możesz dokładniej wyjaśnić, dlaczego chcesz to zrobić? – joran

+3

To nie ma nic wspólnego z głębokim lub płytkim kopiowaniem. –

Odpowiedz

9

Można to zrobić poprzez przypisanie domyślnej wyrażenie dla parametru formalnego j ręcznie, po utworzeniu funkcji:

i <- 3; 
f <- function(x,j) x*j; 
f; 
## function(x,j) x*j 
formals(f); 
## $x 
## 
## 
## $j 
## 
## 
formals(f)$j <- i; 
f; 
## function (x, j = 3) 
## x * j 
formals(f); 
## $x 
## 
## 
## $j 
## [1] 3 
## 
i <- 4; 
f(4); 
## [1] 12 

Jest to możliwe tylko dlatego, że R jest niesamowite język i zapewnia pełną odczytu/zapisuj dostęp do wszystkich trzech specjalnych właściwości funkcji, które są następujące:

  1. Drzewo analizy składające się z treści: body().
  2. Parametry formalne i ich wartości domyślne (które same są analizowane): formals().
  3. Środowisko otaczające (używane do realizacji zamknięć): environment().
5

przypisać go do innej zmiennej, jeśli chcesz ponownie użyć i:

default_value = i 
f = function(x, j = default_value) 
    x * j 
i = 4 
f(4) # 12 

oczywiście, nie należy pozwolić tej zmiennej tylko leżące wokół - to jest tak źle, jak w oryginale kod. Możesz uczynić go "prywatnym" dla tej funkcji, definiując oba razem w lokalnym środowisku:

f = local({ 
    default_value = i 
    function(x, j = default_value) 
     x * j 
})