Skip to content

applying cbind (or any function) across all components in a list

3 messages · Rui Barradas, Hans Thompson

#
Hello,

Let me give it a try.
This last post made it clear, I hope. I have two interpretations of your 
problem.

1. 'l1' only has three columns, corresponding to clusters (genotypes) 
XX, XY and YY, and 'l2' has one less column, corresponding to the 
midpoints between their closest genotype cluster.

2. 'l1' can have any number of columns and 'l2' is the same as above, 
i.e., has one less column.

In any case, the result is not the pairwise products of all possible 
combinations of columns of 'l1' and 'l2' matrices, but only those at a 
certain distance. In this case, fun2 below is more general.

fun1 <- function(x, y){
     cbind((x[, 1] + y[, 1])/2, (x[, 2] + y[, 1])/2,
         (x[, 2] + y[, 2])/2, (x[, 3] + y[, 2])/2)
}


fun2 <- function(x, y){
     midpoint <- function(i, j) (x[, i] + y[, j])/2

     colx <- ncol(x)
     res <- matrix(nrow = nrow(x), ncol = 2*colx - 2)
     k <- 1
     res[, k] <- midpoint(1, 1)
     for(cx in seq_len(colx)[-c(1, colx)])
         for(dist in 1:0)
             res[, k <- k + 1] <- midpoint(cx, cx - dist)
     res[, k + 1] <- midpoint(colx, colx - 1)
     res
}

lapply(seq_len(length(l1)), function(i) fun1(l1[[i]], l2[[i]]))
lapply(seq_len(length(l1)), function(i) fun2(l1[[i]], l2[[i]]))


If I'm wrong, sorry for the mess.

Rui Barradas


Em 25-05-2012 11:00, r-help-request at r-project.org escreveu:
#
Hello,

The use of function(i) is because there are two list to be processed, 
with just one I would have used a simpler form of lapply. I don't 
rebember exactly who wrote this in a post some time ago (Michael 
Weylandt?) but imagine a list is a train. Then, list[ i ] is a car and 
list[[ i ]] is the passengers. In your case they are matrices. In the 
case only one list was to be processed, this would do:

lapply(l1, colSums) # for each matrix, apply the function
# more complicated function, typically, not part of base R (or other 
packages)
lapply( l1, function(x) log(1 + colSums(x)) )
# same as above, but the former uses an unnamed, temporary, function, 
that we can dispose of.
f <- function(x) log(1 + colSums(x))
lapply(l1, f)

In my previous post, seq_len guarantees that the index vector is well 
formed. If the list has zero elements, the form 1:length(l1) becomes 1:0 
== c(1, 0) but seq_len(0) == integer(0).
Then, function(i) is a function of the indices 1, 2, ..., length(l1). 
And both 'l1' and 'l2' can be indexed at the same time.

Rui Barradas

Em 25-05-2012 22:30, Hans Thompson escreveu: