Как написать функцию, которая использует один вывод другой функции в качестве отправной точки для нового анализа?

У меня возникли проблемы с написанием функции, которая вызывает другую функцию и использует выходные данные в качестве основы для запуска нового анализа в цикле (или аналогичном). Например, предположим, что функция 1 создает этот вывод: 10. Вторая функция возьмет это как отправную точку для запуска нового анализа. Единственная точка данных из второго вывода затем станет основой для следующего раунда анализа и так далее.

Вот простой пример. Вопрос в том, как создать цикл for для этого. Или, возможно, есть более эффективный способ использования lapply. В любом случае первая функция может быть следующей:

f.1 <-function(x) {
  x
  a <-seq(x,by=1,length.out=5)
  a.1 <-tail(a,1) 
}

Вторая функция, которая вызывает первую функцию, может работать следующим образом:

f.2 <-function(x) {

  f.1 <-function(x) {
    a <-seq(x,by=1,length.out=5)
    a.1 <-tail(a,1) 
  }
  z <-f.1(x)
  y=z+1
  seq(y,by=1,length.out=5)
}

Как я могу изменить f.2(), чтобы он повторно запускал это вычисление, используя предыдущий вывод в качестве основы для следующего раунда анализа. Если быть точным, f.1(10) выводит:

[1] 14

В свою очередь, f.2(10) приводит к:

[1] 15 16 17 18 19

Как я могу переписать f.2() так, чтобы он автоматически вычислял f.2(19) на следующей итерации и постоянно делал это в течение нескольких циклов. В процессе я хотел бы собрать результаты в отдельный файл для просмотра. Спасибо большое!


person James Picerno    schedule 09.10.2014    source источник
comment
Посмотрите на функцию Reduce.   -  person IRTFM    schedule 09.10.2014


Ответы (2)


Вы можете попробовать это с двумя аргументами для f.2. Первый аргумент — это значение x, которое необходимо для инициализации x, а n — количество итераций, которые вы хотите выполнить. Результатом функции будет матрица, содержащая n строк и 5 столбцов.

  f.2 <-function(x, n) {
  c <- matrix(nrow=n, ncol=5)

  for (i in 1:nrow(c))
  {
    z <-f.1(x) ##if you have already defined your f.1(x) beforehand, there is no need to define it again in f.2. you can simply use z <- f.1(x) like it is done here
    y=z+1
    c[i,] = seq(y, by=1, length.out=5)
    x = c[i,5]
  }
  return(c)
}

Результат

 f <- f.2(10, 10)  ##initialising x with 10 and running 10 loops
 f

      [,1] [,2] [,3] [,4] [,5]
 [1,]   15   16   17   18   19
 [2,]   24   25   26   27   28
 [3,]   33   34   35   36   37
 [4,]   42   43   44   45   46
 [5,]   51   52   53   54   55
 [6,]   60   61   62   63   64
 [7,]   69   70   71   72   73
 [8,]   78   79   80   81   82
 [9,]   87   88   89   90   91
[10,]   96   97   98   99  100
person j1897    schedule 09.10.2014
comment
Спасибо, technOslerphile. Это именно то, что я искал. Отличная работа. Очень признателен! Тем не менее, ответ MrFlick также информативен. В общем, отличная пара ответов. Задача решена! - person James Picerno; 10.10.2014

Библиотека magrittr (которая в первую очередь используется dplyr) делает этот тип цепочек несколько простым. Сначала определите функции,

f.1 <-function(x) {
  x
  a <- seq(x, by=1, length.out=5)
  a.1 <- tail(a,1) 
}


f.2 <-function(x) {
  y <- x+1
  seq(y, by=1, length.out=5)
}

тогда

library(magrittr)

f.1(10) %>% f.2
# [1] 15 16 17 18 19

Как упоминалось в @BondedDust, вы можете использовать Reduce, хотя обычно предполагается использовать одну и ту же функцию снова и снова, поэтому вам просто нужно перевернуть наиболее распространенный вариант использования.

Reduce(function(x,f) f(x), list(f.1, f.2), init=10)
# [1] 15 16 17 18 19
person MrFlick    schedule 09.10.2014
comment
Спасибо за ваше решение. Хороший дополнительный контекст, если рассматривать его с ответом technOslerphile. Функция Reduce() особенно информативна. Не знал о Reduce() до этого, и вы довольно ясно продемонстрировали его ценность. Хорошо сделано. - person James Picerno; 10.10.2014