Friday, 15 February 2013

R-apply a function to each row of a matrix, with a changing argument? -



R-apply a function to each row of a matrix, with a changing argument? -

i have function 2 arguments. first argument takes vector, , sec argument takes scalar. want apply function each row of matrix, function takes different sec argument every time. tried following, didn't work. expected calculate p.value each row , split p.value row number. expected result vector, got matrix instead. pseudo example, illustrates purpose.

> foo = matrix(rnorm(100),ncol=20) > f = function (x,y) t.test(x[1:10],x[11:20])$p.value/y > goo = 1:5 > apply(foo,1,f,y=goo) [,1] [,2] [,3] [,4] [,5] [1,] 0.9406881 0.6134117 0.5484542 0.11299535 0.20420786 [2,] 0.4703440 0.3067059 0.2742271 0.05649767 0.10210393 [3,] 0.3135627 0.2044706 0.1828181 0.03766512 0.06806929 [4,] 0.2351720 0.1533529 0.1371135 0.02824884 0.05105196 [5,] 0.1881376 0.1226823 0.1096908 0.02259907 0.04084157

the next loop strategy produces expected result, expect slow real data.

> res = numeric(5) > (i in 1:5){ res[i]=f(foo[i,],i) } > res [1] 0.94068810 0.30670585 0.18281807 0.02824884 0.04084157

any suggestions appreciated!

if real purpose example, can vectorize division:

f <- function(x) t.test(x[1:10], x[11:20])$p.value apply(foo, 1, f) / goo

based on comment, above not appropriate.

in case of example, might observe diagonal of returned matrix desired result:

f = function (x,y) t.test(x[1:10],x[11:20])$p.value/y goo = 1:5 diag(apply(foo,1,f,y=goo))

besides beingness inefficient in time or space, suffers problem. result of operation on y beingness vectorized right example. , in case, former solution better. suspect in actual problem, operation not vectorized.

sometimes for loop best answer. apply family of functions not magical; still loops.

here sapply solution. won't beat for time (probably won't lose either) doesn't have high space overhead. thought apply row index , utilize extract row of foo , element of goo pass f

sapply(seq(nrow(foo)), function(i) f(foo[i,], goo[i]))

r apply

No comments:

Post a Comment