Поиск всех перестановок и вызов функции для результатов в R - PullRequest
1 голос
/ 04 мая 2019

Необходимо написать функцию permn(m,n,FUN), которая находит все перестановки m размера n и возвращает вектор значений, возвращаемых путем вызова FUN для каждой перестановки, но пытается выяснить, как вызывать FUN для каждой из них.

Поскольку мы не заботимся об эффективности, я решил сначала вычислить все перестановки, используя функцию permutations(), а затем передать вектор перестановок в FUN.Однако это работает только в тех случаях, когда FUN не требует доступа к определенному индексу вектора.

permn <- function(m, n, FUN=NULL) {
  result <- c()
  if (length(m) == 1) {
    p <- permutations(length(1:m),n,1:m)
  } else {
    p <- permutations(length(m),n,m)
  }

  result <- FUN(p)
  return(result)
}

Если я сделаю следующее, permn(4,2,function(x){2*x}), FUN будет применен к каждому элементу матрицы,и я получаю правильный вывод, матрица 12x2.Однако передача функции, такой как first <- function(z) z[1], которая должна возвращать первый элемент каждой перестановки, возвращает только один элемент.Например, вызов permn(7:10,2,first) должен возвращать [1] 7 7 7 8 8 8 9 9 9 10 10 10 из матрицы, которая выглядит как

[1,] 7 8

[2,] 7 9

[3,] 7 10

[4,] 8 7

...

, но вместо этого возвращает 7.Как я могу сделать так, чтобы FUN применялся к каждой перестановке в векторе?

1 Ответ

0 голосов
/ 04 мая 2019

Вы можете использовать purrr::map или базовую R sapply:

first <- function(z) purrr::map_dbl(z[,1], ~.x[1])

# alternate
# first <- sapply(z[,1], function(x) x[1])

permn(7:10, 2, first)
#  7  7  7  8  8  8  9  9  9 10 10 10

Обновление для комментариев OP
Если вам нужно сохранить first() как есть, просто оберните map внутри permn, вот так:

first <- function(z) z[1]

permn <- function(m, n, FUN=NULL) {
  result <- c()
  if (length(m) == 1) {
    p <- permutations(length(1:m),n,1:m)
  } else {
    p <- permutations(length(m),n,m)
  }

  result <- purrr::map_dbl(p[,1], FUN)
  return(result)
}

permn(7:10, 2, first)
#  7  7  7  8  8  8  9  9  9 10 10 10
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...