kjo
kjo

Reputation: 35331

Generating a matrix by applying function to all pairs

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

Answers (2)

Andrew Gustar
Andrew Gustar

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

d.b
d.b

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

Related Questions