рекурсивно разделенные элементы списка - PullRequest
3 голосов
/ 02 февраля 2012

Не могу найти правильное заклинание Reduce, Recall, lapply для выполнения следующей задачи.Рассмотрим следующую функцию:

bisect.df <- function(d){
  n <- ncol(d)
  if(n%%2) n <- n-1 # drop one col if odd number
  ind <- sample(n)[seq.int(n/2)] # split randomly both parts

  list(first=d[, ind],
       second=d[, -ind])
}

с учетом data.frame, она возвращает список двух дочерних элементов data.frames с равным ncol, извлеченных случайным образом из их родителя.Я хочу применить эту функцию рекурсивно к потомкам до определенного уровня, скажем, 3 поколения.Я могу сделать это тривиально по одному поколению за раз,

bisect.list <- function(l){
  unlist(lapply(l, bisect.df), recursive=FALSE)
}

, но как я могу назвать это рекурсивно, скажем, N=3 раз?

Вот тестовый образец для игры с

d <- data.frame(matrix(rnorm(16*5), ncol=16))
step1 <- bisect.list(list(d))
step2 <- bisect.list(step1)
step3 <- bisect.list(step2)
str(list(step1, step2, step3))

Ответы [ 2 ]

2 голосов
/ 02 февраля 2012

Вот рекурсивное решение: идея состоит в том, чтобы добавить аргумент, который подсчитывает количество оставшихся рекурсивных вызовов.(Но он делает то же самое, что и версия цикла.)

f <- function( d, n=3 ) {
  if( is.data.frame( d ) )
    return( f( list(d), n ) )
  if( n == 0 )
    return( d )
  result <- lapply( d, bisect.df )
  result <- unlist( result, recursive=FALSE )
  result <- f( result, n-1 )
  result
}
d <- as.data.frame( t(1:20) )
f(d)

Может быть проще просто взять индексы столбцов в произвольном порядке и построить все подкадры данных сразу.

2 голосов
/ 02 февраля 2012
bisect.list <- function(l,n){
  for(i in 1:n) {
    l <- unlist(lapply(l, bisect.df), recursive=FALSE)
  }
  return(l)
}

не уверен, как это сделать без цикла ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...