30
votes

What if one wants to apply a functon i.e. to each row of a matrix, but also wants to use as an argument for this function the number of that row. As an example, suppose you wanted to get the n-th root of the numbers in each row of a matrix, where n is the row number. Is there another way (using apply only) than column-binding the row numbers to the initial matrix, like this?

test <- data.frame(x=c(26,21,20),y=c(34,29,28))

t(apply(cbind(as.numeric(rownames(test)),test),1,function(x) x[2:3]^(1/x[1])))

P.S. Actually if test was really a matrix : test <- matrix(c(26,21,20,34,29,28),nrow=3) , rownames(test) doesn't help :( Thank you.

5
Note that in your example you don't need the apply!Jonathan Chang
Yes, I can see that :) Actually I wanted to draw some lines on a plot at positions associated with the line number.Brani

5 Answers

33
votes

What I usually do is to run sapply on the row numbers 1:nrow(test) instead of test, and use test[i,] inside the function:

t(sapply(1:nrow(test), function(i) test[i,]^(1/i)))

I am not sure this is really efficient, though.

3
votes

If you give the function a name rather than making it anonymous, you can pass arguments more easily. We can use nrow to get the number of rows and pass a vector of the row numbers in as a parameter, along with the frame to be indexed this way.

For clarity I used a different example function; this example multiplies column x by column y for a 2 column matrix:

test <- data.frame(x=c(26,21,20),y=c(34,29,28))
myfun <- function(position, df) {
    print(df[position,1] * df[position,2])
}

positions <- 1:nrow(test)
lapply(positions, myfun, test)
2
votes

cbind()ing the row numbers seems a pretty straightforward approach. For a matrix (or a data frame) the following should work:

apply( cbind(1:(dim(test)[1]), test), 1, function(x) plot(x[-1], main=x[1]) )

or whatever you want to plot.

2
votes

Actually, in the case of a matrix, you don't even need apply. Just:

test^(1/row(test))

does what you want, I think. I think the row() function is the thing you are looking for.

0
votes

I'm a little confuse so excuse me if I get this wrong but you want work out n-th root of the numbers in each row of a matrix where n = the row number. If this this the case then its really simple create a new array with the same dimensions as the original with each column having the same values as the corresponding row number:

test_row_order = array(seq(1:length(test[,1]), dim = dim(test))

Then simply apply a function (the n-th root in this case):

n_root = test^(1/test_row_order)