Need to write a function permn(m,n,FUN) that finds all permutations of m of size n, and returns a vector of values returned by calling FUN on each permutation, but struggling to figure out how to call FUN on each one.

Since we don't care about efficiency, I decided to first compute all the permutations using the permutations() function, and then pass the vector of permutations into FUN. However, this only works in cases where FUN doesn't require accessing a specific index of the vector.

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)
}

If I do the following, permn(4,2,function(x){2*x}), FUN is applied to each element in the matrix, and I get the correct output, a 12x2 matrix. However, passing a function such as first <- function(z) z[1] which is supposed to return the first element of each permutation, only returns a single element. For example, calling permn(7:10,2,first) is supposed to return [1] 7 7 7 8 8 8 9 9 9 10 10 10 from a matrix that looks like

[1,] 7 8

[2,] 7 9

[3,] 7 10

[4,] 8 7

...

but instead returns 7. How can I make it so that FUN is applied to each permutation in the vector?

1 Answers

0
andrew_reece On

You can use purrr::map or base 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

Update per OP comments
If you need to keep first() as-is, just wrap with map inside permn, like this:

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