Home > Software design >  How to make an R function to turn a vector into a matrix?
How to make an R function to turn a vector into a matrix?

Time:11-12

I am just learning R and got to functions. I have made a function of 0 or more variables, but they always return one value. I can make a function that returns a vector of values using c(x,y,z), but when I input a vector, it just returns a longer vector. For example if I make a function f <- function(x) { c(x, x^2, x^3) } and pass it 2, it returns 2, 4, 8. But if i pass it the vector 2,3,4, it returns 2,4,8,3,9,27,4,16,64. Where I would like a matrix with 3 rows corresponding to the 3 inputs I gave it, and 3 columns with the return values. So a 3x3 matrix with the columns (2,3,4),(4,9,16),(8,27,64). I would also love to be able to do this using base functionality, although if I have to use a package to do this that would also be fine

tried input (2,3,4). wanted output:

2   4   8
3   9  27
4  16  64

but got (2,4,8,3,9,27,4,16,64).

CodePudding user response:

I think cbind is all you need here:

f <- function(x)  cbind(x, x^2, x^3) 

f(c(2, 3, 4))
#>      x      
#> [1,] 2  4  8
#> [2,] 3  9 27
#> [3,] 4 16 64

However, any solution involving a single call to matrix or cbind with an atomic value of x (such as f(2)) will produce a single-row matrix rather than a vector. If you want a vector rather than a matrix in this situation, you can do

f <- function(x)  (if(length(x) == 1) c else cbind)(x, x^2, x^3) 

f(c(2, 3, 4))
#>      x      
#> [1,] 2  4  8
#> [2,] 3  9 27
#> [3,] 4 16 64

f(2)
#> [1] 2 4 8

Created on 2022-11-11 with reprex v2.0.2

CodePudding user response:

Using matrix(), with nrow set to the length of the input vector:

f <- function(x) {
  matrix(c(x, x^2, x^3), nrow = length(x))
} 

f(c(2, 3, 4))

#>      [,1] [,2] [,3]
#> [1,]    2    4    8
#> [2,]    3    9   27
#> [3,]    4   16   64

Created on 2022-11-11 with reprex v2.0.2

CodePudding user response:

You can use outer() to make the function scale to accept an arbitrary length vector.

f <- function(x) {
  y <- seq_along(x)
  outer(x, y, "^")
} 

x <- 2:4

f(x)
#>      [,1] [,2] [,3]
#> [1,]    2    4    8
#> [2,]    3    9   27
#> [3,]    4   16   64

Created on 2022-11-11 with reprex v2.0.2

CodePudding user response:

Another answer with outer(). You can provide one vector of bases and one of exponents:

f <- function(x,y) x^y

outer(
    c(2,3,4),
    c(1,2,3), 
    f
)

Output:

#      [,1] [,2] [,3]
# [1,]    2    4    8
# [2,]    3    9   27
# [3,]    4   16   64

This also produces the desired output if the vectors are not of the same length.

  • Related