Suppose I want to apply a function to each row of a matrix. One of the function's arguments takes a vector. I would like to apply the first element of the vector to the first row, the second element to the second row, etc.
For example:
set.seed(123)
df<-matrix(runif(100), ncol=10)
var2 <- c(1:10)
MYFUNC <- function(x, Var=NA){
sum(x)/Var
}
I tried this:
apply(df, 1, function(x) MYFUNC(x, Var=var2))
But that gives me a 10x10 matrix with the function applied to each row & Var combination, whereas I'm only interested in the diagonal elements. I also looked into the mapply
function, but I'm not sure how to apply it in this case.
Any help would be really appreciated.
Mapply
is definitely a possibility. This should work:
mapply(MYFUNC, x = as.data.frame(t(df)), Var = var2)
#V1 V2 V3 V4 V5 V6 V7 V8 V9 V10
#5.0795111 2.8693537 1.8285747 1.3640238 0.8300597 0.6280441 0.7706310 0.6720132 0.5719003 0.4259674
The issue I think you were running into is that mapply
takes either vectors or lists. In R matrices aren't lists, but data.frame
s are. All you need to do is transpose your matrix and convert to a data.frame
and then mapply
should work. Each column in a data.frame
is an element in the list which is why we have to transpose it (so that each row
will be mapped to each element in the vector).
As there are two arguments that should be the corresponding rows and elements in matrix/vector respectively, we can loop through the sequence of rows, subset the data and apply the function
sapply(seq_len(nrow(df)), function(i) MYFUNC(df[i,], Var = var2[i]))
#[1] 5.0795111 2.8693537 1.8285747 1.3640238 0.8300597 0.6280441
#[7] 0.7706310 0.6720132 0.5719003 0.4259674
For the specific example, it can be vectorized with rowSums
rowSums(df)/var2
#[1] 5.0795111 2.8693537 1.8285747 1.3640238 0.8300597 0.6280441
#[7] 0.7706310 0.6720132 0.5719003 0.4259674