Функция внутри функции на языке R - PullRequest
3 голосов
/ 12 июня 2019

У меня есть простая функция на языке R, например:

f<-function(x){
y=(x+2)/3
return(y)
}

Я хочу оценить эту функцию пять раз на ее собственных выходах, то есть y1=f(x), y2=f(f(x)), y3=f(f(f(x))), y4=f(f(f(f(x)))), y5=f(f(f(f(f(x))))).Существует ли более простой способ сделать это в виде одной функции, например, функции с двумя аргументами, когда первый аргумент равен x, а второй аргумент - это число раз оценки, то есть n.Например, для x=3 и n=5 я хотел бы иметь функцию f2<-(x=3,n=5), чей вывод был бы в форме вектора или списка длины, равной n со значениями:

y1=f(3)=1.666667
y2=f(f(3))=1.222222
y3=f(f(f(3)))=1.074074
y4=f(f(f(f(3))))=1.024691
y5=f(f(f(f(f(3)))))=1.00823

Как написать такую ​​функцию в R?

Ответы [ 4 ]

4 голосов
/ 12 июня 2019

Используя принятый ответ в другом сообщении, просто используйте Reduce для создания композиции, g.

composite <- function(g, h) {function(...)g(h(...))}
g <- Reduce(composite, list(f, f, f, f, f))

g(2)
f(f(f(f(f(2)))))

identical(g(2), f(f(f(f(f(2))))))
#[1] TRUE
3 голосов
/ 12 июня 2019

Вы можете написать вспомогательную функцию, например:

iterate <- function(f,s,n){
  iterates <- vector(length = n+1)
  iterates[1] <- s
  for(i in 1:n){
    iterates[i+1] <- f(iterates[i])
  }
  iterates
}

Затем, например,

> iterate(function(x){(x+2)/3},3,5)
[1] 3.000000 1.666667 1.222222 1.074074 1.024691 1.008230

Вы, конечно, можете изменить приведенный выше код так, чтобы вектор начинался с f(s), а не s.

2 голосов
/ 12 июня 2019

Вы также можете настроить исходную функцию, как показано ниже:

f2<-function(x, steps){
             ans<-c(x)
              for (i in 1:steps) {
                   y=(x+2)/3
                   ans=append(ans,y)
                   x = y
  }
    return(ans)
}

f2(3,5)
#> [1] 3.000000 1.666667 1.222222 1.074074 1.024691 1.008230
1 голос
/ 12 июня 2019

Reduce сделает это, если вы добавите аргумент «мусор» в ваш f.Если вам нужен только последний набор результатов accumulate = F или просто удалите аргумент accumulate из функции

f<-function(x, junk){
y=(x+2)/3
return(y)
}

Reduce(f, x = numeric(5), init = 3, accumulate = T)
# [1] 3.000000 1.666667 1.222222 1.074074 1.024691 1.008230

Или с помощью purrr

purrr::accumulate(numeric(5), f, .init = 3)
# [1] 3.000000 1.666667 1.222222 1.074074 1.024691 1.008230
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...