[R] apply: return list of matrices

Thaler, Thorn, LAUSANNE, Applied Mathematics Thorn.Thaler at rdls.nestle.com
Tue Jul 20 11:29:11 CEST 2010


Hi everybody,

Suppose we have the following data structure:

ddf <-data.frame(a=rep(1:4,3), b=rep(paste("p", 1:3, sep=""), each=4),
c=c(1,0,0,1,1,1,0,1,1,1,1,1))

I want now to make a contingency table for each pair of values of p,
i.e. a contingency table for each of the pairs (p1,p2), (p1,p3) and
(p2,p3). The result should be given as a list of matrices: 

# [[1]] <=> (p1, p2)
# [[2]] <=> (p1, p3)
# [[3]] <=> (p2, p3)
[[1]] 
     [,1] [,2]
[1,]    1    1
[2,]    0    2

[[2]]
     [,1] [,2]
[1,]    0    2
[2,]    0    2

[[3]]
     [,1] [,2]
[1,]    0    1
[2,]    0    3

Basically, I achieved what I want except that the output format is not
the way it should be:

ct <- function(bc) {
  n <- length(bc)
  bc <- factor(bc)
  table(bc[1:(n/2)], bc[(n/2+1):n])
}

ct returns a 2x2 table giving the contingency counts.

f <- function(p, b) {
  allC <- t(combn(levels(as.factor(p)), 2))
  bRaw <- apply(allC, 1, function(x) cbind(b[p==x[1]], b[p==x[2]]))
	
  # bRaw would preferable be already a list of nx2 matrices, but apply
coerces the result to a single matrix, 
  # whose columns are rbind(b[p==x[1]], b[p==x[2]]), that's why "ct"
takes just one argument and splits the vector

  apply(bRaw, 2, ct)
}

Again the result is one single matrix instead of list of matrices (the
columns consist of the values of the matrices). I suppose that apply
does some sophisticated simplification on the result vector, but how can
I circumvent this mechanism? For the time being I made another *apply
call, which gives me the same result in the format I'd like: just
replace the last line in function f by

lapply(apply(bRaw, 2, function(x) list(ct(x))), function(x)
matrix(unlist(x),2,2))

However, is an additional lapply call really necessary?

Thanks 4 ur input,

Thorn



More information about the R-help mailing list