Podpowiedziane przez @ hadley's article on functionals referenced in an answer today, postanowiłem wrócić do uporczywej łamigłówki o tym, jak działa funkcja outer
(lub nie). Dlaczego tego nie robi:Dlaczego praca zewnętrzna nie wygląda tak, jak powinien (w R)?
outer(0:5, 0:6, sum) # while outer(0:5, 0:6, "+") succeeds
To pokazuje, jak myślę outer
powinny obsługiwać funkcji takich jak sum
:
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, ja nie mam indeksy dokładnie dopasowane do tego przykładu, ale nie byłoby to trudne do naprawienia. Pytanie brzmi, dlaczego funkcja taka jak sum
, która powinna być w stanie przyjąć dwa argumenty i zwrócić (atomową) wartość odpowiednią dla elementu macierzy, nie może tego zrobić po przejściu do funkcji base::outer
?
Więc @agstudy dał natchnienie dla bardziej kompaktowej wersji Outer
i jego jest jeszcze bardziej kompaktowy:
Outer <- function(x,y,fun) {
mat <- matrix(mapply(fun, rep(x, length(y)),
rep(y, each=length(x))),
length(x), length(y))
Jednak pytanie pozostaje. Termin "wektoryzacja" jest tu nieco niejednoznaczny i myślę, że "diadyczna" jest bardziej poprawna, ponieważ sin
i cos
są "wektoryzowane" w zwykłym tego słowa znaczeniu. Czy istnieje podstawowa logiczna bariera, aby oczekiwać, że outer
rozszerzy swoje argumenty w taki sposób, aby można było użyć funkcji nieadadycznych.
A oto kolejny outer
-error że prawdopodobnie podobnie podłączony do mojego braku zrozumienia tego problemu:
> 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]
Twoje funkcje są w porządku, ale zgaduję, że jest znacznie wolniej, więc nie jest to zbyt dobre dla implementacji R 'zewnętrznego'; był zewnętrzny zaimplementowany w C++ zamiast tego, wersja 'sum' prawdopodobnie pracowała – eddi
, której szukasz w swoim ostatnim przykładzie:' zewnętrzny (0: 5, 0: 6, Vectorize (suma funkcji (x, y) (x, y))) ' – eddi
@eddi: Chciałbym przegłosować, że jeśli oferowane jako odpowiedź. –