Por que o trabalho externo não funciona do jeito que eu acho que deveria (em R)?
Solicitado por @ hadleyartigo sobre funcionais referenciados em uma resposta hoje, Eu decidi revisitar um quebra-cabeça persistente sobre como oouter
função funciona (ou não). Por que isso falha:
outer(0:5, 0:6, sum) # while outer(0:5, 0:6, "+") succeeds
Isso mostra como eu pensoouter
devemos lidar com uma função comosum
:
Outer <- function(x,y,fun) {
mat <- matrix(NA, length(x), length(y))
for (i in seq_along(x)) {
for (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, não tenho meus índices alinhados exatamente para esse exemplo, mas não seria tão difícil de corrigir. A questão é por que uma função comosum
que deve ser capaz de aceitar dois argumentos e retornar um valor (atômico) adequado para um elemento de matriz, não pode fazê-lo quando passado para obase::outer
função?
Então, @agstudy deu inspiração para uma versão mais compacta doOuter
e o dele é ainda mais compacto:
Outer <- function(x,y,fun) {
mat <- matrix(mapply(fun, rep(x, length(y)),
rep(y, each=length(x))),
length(x), length(y))
No entanto, a questão permanece. O termo "vetorizado" é um pouco ambíguo aqui e eu acho que "diádico" é mais correto, já quesin
ecos
são "vetorizados" no sentido usual do termo. Existe uma barreira lógica fundamental para esperarouter
para expandir seus argumentos de uma maneira que funções não-diádicas possam ser usadas.
E aqui está outroouter
- erro que provavelmente está similarmente relacionado à minha falta de compreensão deste problema:
> 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] do not match the length of object [1]