apply a function separately on each element of a list

10,302

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]
)
Share:
10,302
jeff6868
Author by

jeff6868

Updated on June 04, 2022

Comments

  • jeff6868
    jeff6868 almost 2 years

    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!