Reputation: 35331
Let F
be a function that takes two arguments and returns a numeric value, and let X
and Y
be vectors of values suitable as first and second arguments (respectively) of F
.
Is there a "functional" (i.e. loop-free), and convenient, way to generate the matrix whose ij-th entry is the number
F(X[[i]], Y[[j]])
?
In Python, I would do this:
[[F(x, y) for y in Y] for x in X]
In Mathematica,
Table[F[x, y], {x, X}, {y, Y}]
Etc.
Is there something similarly straightforward in R?
UPDATE: regarding outer
:
> F <- function (c1, c2) utf8ToInt(c1) - utf8ToInt(c2)
This F
is just a silly example to illustrate my point. It works when used by itself:
> F('A', 'a')
[1] -32
But:
> outer(c('A', 'B', 'C', 'D', 'E'), c('a', 'b', 'c', 'd', 'e'), F)
Error in outer(c("A", "B", "C", "D", "E"), c("a", "b", "c", "d", "e"), :
dims [product 25] do not match the length of object [1]
In addition: Warning messages:
1: In utf8ToInt(c1) : argument should be a character vector of length 1
all but the first element will be ignored
2: In utf8ToInt(c2) : argument should be a character vector of length 1
all but the first element will be ignored
I repeat, the above is just an artificial example, concocted only to illustrate my point. (Therefore, getting it to work in a non-generalizable way is of no use to me.)
Upvotes: 2
Views: 393
Reputation: 18445
According to the help for outer
, F needs to be vectorised...
F <- Vectorize(function (c1, c2) utf8ToInt(c1) - utf8ToInt(c2))
outer(c('A', 'B', 'C', 'D', 'E'), c('a', 'b', 'c', 'd', 'e'), F)
Upvotes: 1
Reputation: 32558
Either vectorize F
so that you can use it with outer
or do something like below
sapply(c('A', 'B', 'C', 'D', 'E'), function(a)
sapply(c('a', 'b', 'c', 'd', 'e'), function(b)
F(a,b)))
# A B C D E
#a -32 -31 -30 -29 -28
#b -33 -32 -31 -30 -29
#c -34 -33 -32 -31 -30
#d -35 -34 -33 -32 -31
#e -36 -35 -34 -33 -32
Upvotes: 1