R - apply a function with a different argument value for each row / column of the matrix

I am trying to apply a function to each row or column of a matrix, but I need to pass a different argument value for each row.

I thought I was familiar with the foot, mapply, etc. But this is probably not enough.

As a simple example:

> a<-matrix(1:100,ncol=10);
> a
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
 [1,]    1   11   21   31   41   51   61   71   81    91
 [2,]    2   12   22   32   42   52   62   72   82    92
 [3,]    3   13   23   33   43   53   63   73   83    93
 [4,]    4   14   24   34   44   54   64   74   84    94
 [5,]    5   15   25   35   45   55   65   75   85    95
 [6,]    6   16   26   36   46   56   66   76   86    96
 [7,]    7   17   27   37   47   57   67   77   87    97
 [8,]    8   18   28   38   48   58   68   78   88    98
 [9,]    9   19   29   39   49   59   69   79   89    99
[10,]   10   20   30   40   50   60   70   80   90   100

      

Let's say I want to apply a function to each line, I would do:

apply(a, 1, myFunction);

      

However, my function takes an argument, so:

apply(a, 1, myFunction, myArgument);

      

But if I want my argument to take a different value for each line, I cannot find the correct way to do it. If I define "myArgument" with multiple values, the entire vector will obviously be passed to every call to "myFunction".

I think I need a hybrid between application and multidimensional mapply. Does it make sense?

One dirty way to achieve my goal is to split the matrix into rows (or columns), use mapply on the resulting list, and concatenate the result back into the matrix:

do.call(rbind, Map(myFunction, split(a,row(a)), as.list(myArgument)));

      

I've looked at sweep, aggregate, all use cases *, but I wouldn't find a perfect match for my need. Did I miss this?

Thank you for your help.

+3


source to share


3 answers


You can use sweep

for this.



a <- matrix(rnorm(100),10)
rmeans <- rowMeans(a)
a_new <- sweep(a,1,rmeans,`-`)
rowMeans(a_new)

      

+1


source


I don't think there are great answers, but you can simplify your solution a bit by using mapply

which handles the "rbind" part for you if your function always returns the same vector size (also, Map

really simple mapply

):



a <- matrix(1:80,ncol=8)
myFun <- function(x, y) (x - mean(x)) * y
myArg <- 1:nrow(a)

t(mapply(myFun, split(a, row(a)), myArg))

      

0


source


I know the topic is quiet, but I had the same problem and solved it like this:

# Original matrix
a <- matrix(runif(n=100), ncol=5)
# Different value for each row
v <- runif(n=nrow(a))
# Result matrix -> Add a column with the row number
o <- cbind(1:nrow(a), a)
fun <- function(x, v) {
  idx <- 2:length(x)
  i <- x[1]
  r <- x[idx] / v[i]
  return(r)
}
o <- t(apply(o, 1, fun, v=v)

      

By adding a column with a row number to the left of the original matrix, the index of the desired value from the argument vector can be obtained from the first column of the data matrix.

0


source







All Articles