2017-01-28 2 views
0

Я хотел бы создать список функций в R, где значения из цикла for хранятся в определении функции. Вот пример:R: Использование переменной Loop в объявлении функции

init <- function(){ 
    mod <- list() 
    for(i in 1:3){ 
    mod[[length(mod) + 1]] <- function(x) sum(i + x) 
    } 
    return(mod) 
} 

mod <- init() 

mod[[1]](2) # 5 - but I want 3 
mod[[2]](2) # 5 - but I want 4 

В приведенном выше примере, независимо от того, какую функцию я называю, i всегда последнее значение в для последовательности петли, я понимаю, что это правильное поведение.

Я ищу что-то, что добивается этого:

mod[[1]] <- function(x) sum(1 + x) 
mod[[2]] <- function(x) sum(2 + x) 
mod[[3]] <- function(x) sum(3 + x) 
+0

Почему? Кажется свернутым. Похоже, вы хотите объявить другую переменную типа 'const <- 2' перед циклом и вместо этого использовать' sum (const + x) '. Все еще очень запутано ... – adatum

+0

Я добавил пример того, как бы хотелось, чтобы каждая функция выглядела. Мой фактический прецедент более сложен. Я просто пытаюсь понять, как работает область действия. – BMW

ответ

2

Вы можете явно обеспечить i оценивается в это текущее значение в течение цикла с помощью force.

init <- function(){ 
    mod <- list() 
    f_gen = function(i) { 
    force(i) 
    return(function(x) sum(i + x)) 
    } 
    for(i in 1:3){ 
    mod[[i]] <- f_gen(i) 
    } 
    return(mod) 
} 

mod <- init() 

mod[[1]](2) 
# [1] 3 
mod[[2]](2) 
# [1] 4 

Подробнее см. В Functions/Lazy Evaluation subsection of Advanced R. Также см. ?force, конечно. Ваш пример довольно похож на примеры, приведенные в ?force.

Использование функции однофункционного генератора (f_gen в моем коде выше), кажется, имеет больше смысла, чем функция генератора функций-функций. С помощью моего f_gen ваш код будет упрощен:

f_gen = function(i) { 
     force(i) 
     return(function(x) sum(i + x)) 
} 
mod2 <- lapply(1:3, f_gen) 

mod2[[1]](2) 
# [1] 3 
mod2[[2]](2) 
# [1] 4 

## or alternately 
mod3 = list() 
for (i in 1:3) mod3[[i]] <- f_gen(i) 
mod3[[1]](2) 
mod3[[2]](2) 
Смежные вопросы