Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
372 views
in Technique[技术] by (71.8m points)

recursion - Can you add rows to a matrix in a recursive loop in R?

Ok, so I wrote this function in R that generates all unique pairings of elements in a list.

pair_generate <- function (vec, start = 1) {

  if (start + 1 == length(vec)) {
    print(vec)
    return()
  }
  
  for (j in seq(start + 1, length(vec), by = 1)) {
    temp = vec[start+1]
    vec[start+1] = vec[j]
    vec[j] = temp
    
    pair_generate(vec, start + 2)
    
    temp = vec[start+1]
    vec[start+1] = vec[j]
    vec[j] = temp
  }
}

When called, this function prints:

pair_generate(1:6)

[1] 1 2 3 4 5 6
[1] 1 2 3 5 4 6
[1] 1 2 3 6 5 4
[1] 1 3 2 4 5 6
[1] 1 3 2 5 4 6
[1] 1 3 2 6 5 4
[1] 1 4 3 2 5 6
[1] 1 4 3 5 2 6
[1] 1 4 3 6 5 2
[1] 1 5 3 4 2 6
[1] 1 5 3 2 4 6
[1] 1 5 3 6 2 4
[1] 1 6 3 4 5 2
[1] 1 6 3 5 4 2
[1] 1 6 3 2 5 4

Now, I want to store the vectors in a matrix instead of just printing them. I modified my function to the following:

pair_generate <- function (vec, start = 1, mat) {

  if (start + 1 == length(vec)) {
    mat <- rbind(mat, matrix(vec, nrow = 1))
    return()
  }
  
  for (j in seq(start + 1, length(vec), by = 1)) {
    temp = vec[start+1]
    vec[start+1] = vec[j]
    vec[j] = temp
    
    pair_generate(vec, start + 2, mat)
    
    temp = vec[start+1]
    vec[start+1] = vec[j]
    vec[j] = temp
  }
}

However, when I create a 0x6 matrix 'sample_mat' then run the modified function on 'sample_mat', it appears unchanged. The following code yields an empty matrix:

sample_mat <- matrix(nrow = 0, ncol = 6)
pair_generate(1:6, mat = sample_mat)
print(sample_mat)

Does anyone know how to fix this problem? How can I store the output of the first function as a matrix?

question from:https://stackoverflow.com/questions/65865700/can-you-add-rows-to-a-matrix-in-a-recursive-loop-in-r

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Don't pass the variable to save data in the function. You can change your function to :

pair_generate <- function (vec, start = 1) {
  
  if (start + 1 == length(vec)) {
    return(vec)
  }
  vals <- seq(start + 1, length(vec), by = 1)
  result <- vector('list', length(vals))
  i <- 0
  for (j in vals) {
    temp = vec[start+1]
    vec[start+1] = vec[j]
    vec[j] = temp
    i <- i + 1
    result[[i]] <- pair_generate(vec, start + 2)
    
    temp = vec[start+1]
    vec[start+1] = vec[j]
    vec[j] = temp
  }
  return(do.call(rbind, result))
}

and then save the output of the function in the variable of your choice.

sample_mat <- pair_generate(1:6)
sample_mat

#      [,1] [,2] [,3] [,4] [,5] [,6]
# [1,]    1    2    3    4    5    6
# [2,]    1    2    3    5    4    6
# [3,]    1    2    3    6    5    4
# [4,]    1    3    2    4    5    6
# [5,]    1    3    2    5    4    6
# [6,]    1    3    2    6    5    4
# [7,]    1    4    3    2    5    6
# [8,]    1    4    3    5    2    6
# [9,]    1    4    3    6    5    2
#[10,]    1    5    3    4    2    6
#[11,]    1    5    3    2    4    6
#[12,]    1    5    3    6    2    4
#[13,]    1    6    3    4    5    2
#[14,]    1    6    3    5    4    2
#[15,]    1    6    3    2    5    4

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...