functional programming - Why doesn't outer work the way I think it should (in R)? -


prompted @hadley's article on functionals referenced in answer today, decided revisit persistent puzzle how outer function works (or doesn't). why fail:

outer(0:5, 0:6, sum) # while outer(0:5, 0:6, "+") succeeds 

this shows how think outer should handle function sum:

 outer <- function(x,y,fun) {    mat <- matrix(na, length(x), length(y))    (i in seq_along(x)) {             (j in seq_along(y)) {mat[i,j] <- fun(x[i],y[j])} }    mat}  >  outer(0:5, 0:6, `+`)      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [1,]    0    1    2    3    4    5    6 [2,]    1    2    3    4    5    6    7 [3,]    2    3    4    5    6    7    8 [4,]    3    4    5    6    7    8    9 [5,]    4    5    6    7    8    9   10 [6,]    5    6    7    8    9   10   11 

ok, don't have indices aligned example, wouldn't hard fix. question why function sum should able accept 2 arguments , return (atomic) value suitable matrix element, cannot when passed base::outer function?

so @agstudy has given inspiration more compact version of outer , more compact:

 outer <- function(x,y,fun) {        mat <- matrix(mapply(fun, rep(x, length(y)),                                   rep(y, each=length(x))),                      length(x), length(y)) 

however, question remains. term "vectorized" ambiguous here , think "dyadic" more correct, since sin , cos "vectorized" in usual sense of term. there fundamental logical barrier expecting outer expand arguments in manner non-dyadic functions can used.

and here's outer-error connected lack of understanding of issue:

> vectorize(sum) function (..., na.rm = false)  .primitive("sum") >  outer(0:5, 0:6, function(x,y) vectorize(sum)(x,y) ) error in outer(0:5, 0:6, function(x, y) vectorize(sum)(x, y)) :    dims [product 42] not match length of object [1] 

outer(0:5, 0:6, sum) don't work because sum not "vectorized" (in sense of returning vector of same length 2 arguments). example should explain difference:

 sum(1:2,2:3)   8  1:2 + 2:3  [1] 3 5 

you can vectorize sum using mapply example:

identical(outer(0:5, 0:6, function(x,y)mapply(sum,x,y)),           outer(0:5, 0:6,'+')) true 

ps: before using outer use browser create function in debug mode:

outer(0:2, 1:3, function(x,y)browser()) called from: fun(x, y, ...) browse[1]> x [1] 0 1 2 0 1 2 0 1 2 browse[1]> y [1] 1 1 1 2 2 2 3 3 3 browse[1]> sum(x,y) [1] 27          ## give error  browse[1]> x+y   [1] 1 2 3 2 3 4 3 4 5 ## vectorized 

Comments

Popular posts from this blog

plot - Remove Objects from Legend When You Have Also Used Fit, Matlab -

java - Why does my date parsing return a weird date? -

Need help in packaging app using TideSDK on Windows -