apply a function separately on each element of a list

Tag: r , for-loop Author: whg575 Date: 2012-08-12

I have a question about applying a function on each elements of a list.

Here's my problem:

I have a list of DF (I divided a bigger DF by days):

 mydf <- data.frame(x=c(1:5), y=c(21:25),z=rnorm(1:5))
 mylist <- rep(list(mydf),5)
 names(mylist) <-c("2006-01-01","2006-01-02","2006-01-03","2006-01-04","2006-01-05") 

Don't care about this fake data if it's identical), it's just for the example. I've my results in column "z" for each DF of the list, and 2 other columns "x" and "y" representing some spatial coordinates.

I have another independent DF containing a list of "x" and "y" too, representing some specific regions (imagine 10 regions):

region <- data.frame(x=c(1:10),y=c(21:30),region=c(1:10)) 

The final aim is to have for each 10 regions, a value "z" (of my results) from the nearest point (according to coordinates) of each of the DF of my list. That means for one region: 10 results "z" from DF1 of my list, then 10 other results "z" from DF2, ... My final DF should look like this if possible (for the structure):

final1 <- data.frame("2006-01-01"=rnorm(1:10),"2006-02-01"=rnorm(1:10),
"2006-03-01"=rnorm(1:10),"2006-04-01"=rnorm(1:10),"2006-05-01"=rnorm(1:10))

With one column for one day (so one DF of the list) and one value for each row (so for example for 2006-01-01: the value "z" from the nearest point with the first region).

I already have a small function to look for the nearest value:

min.dist <- function(p, coord){
     which.min( colSums((t(coord) - p)^2) )
}

Then, I'm trying to make a loop to have what I want, but I have difficulties with the list. I would need to put 2 variables in the loop, but it doesn't works.

This works approximately if I just take 1 DF of my list:

    for (j in 1:nrow(region)){

imin <- min.dist(c(region[j,1],region[j,2]),mylist[[1]][,1:2])
imin[j] <- min.dist(c(region[j,1],region[j,2]),mylist[[1]][,1:2])
final <- mylist[[1]][imin[j], "z"]
final[j] <- mylist[[1]][imin[j], "z"]
final <- as.data.frame(final)
} 

But if I select my whole list (in order to have one column of results for each DF of the list in the object "final"), I have errors.

I think the first problem is that the length of "regions" is different of the length of my list, and the second maybe is about adding a second variable for the length of my list. I'm not very familiar with loop, and so with 2-variables loops.

Could you help me to change in the loop what should be changed in order to have what I'm looking for?

Thank you very much!

Other Answer1

You can use lapply() to apply a function over a list.

This should work. It returns a list of vectors.

lapply(mylist, FUN = function(mydf) mydf[apply(region[ , -3], 1, FUN = function(x) which.min(apply(mydf[ , -3], 1, FUN = function(y) dist(rbind(x, y))))), 3])

comments:

Yes, this is it! Perfect! Thanks a lot Sven!