Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mapply basics? - how to create a matrix from two vectors and a function

Tags:

r

matrix

mapply

I am trying create a data.frame from which to create a graph. I have a function and two vectors that I want to use as the two inputs. This is a bit simplified, but basically all I have is:

relGPA <- seq(-1.5,1.5,.2)
avgGPA <- c(-2,0,2)

f <- function(relGPA, avgGPA) 1/(1+exp(sum(relGPA*pred.model$coef[1],avgGPA*pred.model$coef[2])))

and all I want is a data.frame with 3 columns for the avgGPA values, and 16 rows for the relGPA values with the resulting values in the cells.

I apologize for how basic this is, but I assure you I have tried to make this happen without your assistance. I have tried following the examples on the sapply and mapply man pages, but I'm just a little too new to R to see what I'm trying to do.

Thanks!

like image 721
Sam Swift Avatar asked Mar 25 '11 22:03

Sam Swift


People also ask

How do you apply the same functions to all rows and columns of a matrix?

One of the most famous and most used features of R is the *apply() family of functions, such as apply() , tapply() , and lapply() . Here, we'll look at apply() , which instructs R to call a user-specified function on each of the rows or each of the columns of a matrix.

How do you use the matrix function in R?

To create a matrix in R you need to use the function called matrix(). The arguments to this matrix() are the set of elements in the vector. You have to pass how many numbers of rows and how many numbers of columns you want to have in your matrix. Note: By default, matrices are in column-wise order.


1 Answers

Cannot be tested with the information offered, but this should work:

expGPA  <- outer(relGPA, avgGPA, FUN=f) # See below for way to make this "work"

Another useful function when you want to generate combinations is expand.grid and this would get you the "long form":

expGPA2 <-expand.grid(relGPA, avgGPA)
expGPA2$fn <- apply(expGPA2, 1, f)

The long form is what lattice and ggplot will expect as input format for higher level plotting.

EDIT: It may be necessary to construct a more specific method for passing column references to the function as pointed out by djhurio and (solved) by Sam Swift with the Vectorize strategy. In the case of apply, the sum function would work out of the box as described above, but the division operator would not, so here is a further example that can be generalized to more complex functions with multiple arguments. All the programmer needs is the number of the column for the appropriate argument in the "apply()"-ed" function, because (unfortunately) the column names are not carried through to the x argument:

> expGPA2$fn <- apply(expGPA2, 1, function(x) x[1]/x[2])
> str(expGPA2)
'data.frame':   48 obs. of  3 variables:
 $ Var1: num  -1.5 -1.3 -1.1 -0.9 -0.7 ...
 $ Var2: num  -2 -2 -2 -2 -2 -2 -2 -2 -2 -2 ...
 $ fn  : num  0.75 0.65 0.55 0.45 0.35 ...
 - attr(*, "out.attrs")=List of 2
  ..$ dim     : int  16 3
  ..$ dimnames:List of 2
  .. ..$ Var1: chr  "Var1=-1.5" "Var1=-1.3" "Var1=-1.1" "Var1=-0.9" ...
  .. ..$ Var2: chr  "Var2=-2" "Var2= 0" "Var2= 2"

Edit2: (2013-01-05) Looking at this a year later, I realized that SamSwift's function could be vectorized by making its body use "+" instead of sum:

 1/(1+exp( relGPA*pred.model$coef[1] + avgGPA*pred.model$coef[2]) # all vectorized fns
like image 126
IRTFM Avatar answered Oct 01 '22 18:10

IRTFM