vonjd
vonjd

Reputation: 4380

How to vectorize this code in R

Starting from:

m <- matrix(c(12,9,8,31), nrow=2)
(m.obs <- m.exp <- addmargins(m, FUN=sum, quiet=T))

I have the following code:

m.exp[1,1] <- m.obs[1,3] / m.obs[3,3] * m.obs[3,1]
m.exp[1,2] <- m.obs[1,3] / m.obs[3,3] * m.obs[3,2]
m.exp[2,1] <- m.obs[2,3] / m.obs[3,3] * m.obs[3,1]
m.exp[2,2] <- m.obs[2,3] / m.obs[3,3] * m.obs[3,2]

This could be written as a nested loop as follows:

for (row in 1:2) {
  for (column in 1:2) {
    m.exp[row,column] <- m.obs[row,3] / m.obs[3,3] * m.obs[3,column]
  }
}

My question is whether this could also be written in vectorized form. Are there even different ways how one could vectorize this code? Or are there other ways in which one could simplify it?

My aim is to find different possibilities which illustrate how you could make code faster and/or more elegant in R. The idea is of course to have matrices that are much larger than this toy example.

The background for this example is calculating the matrix of expected frequencies from the observed frequencies for a chi-squared test.

Upvotes: 1

Views: 81

Answers (2)

dimitris_ps
dimitris_ps

Reputation: 5951

Try this

(m.obs[-3, 3]/ m.obs[3,3]) %*% t(m.obs[3, -3])

Upvotes: 2

konvas
konvas

Reputation: 14346

You could avoid the loop by writing it as

m.exp[1:2, 1:2] <- m.obs[rep(1:2, 2), 3] *
    m.obs[3, rep(1:2, each = 2)] / m.obs[3,3]

Upvotes: 1

Related Questions