Looping error with lists: for function not works inside purrr::map2 in R

Advertisements

I built a function to use it inside the purrr::map2 function and run it in two lists. When I run the function steps separately it works ok. But apparently in map2 it runs the first time (for the first elements of list .x[[1]] .y[[1]]) and then in the second round throws this error in the for function:

How can I find out why it’s not working?

PS: It’s hard to put an example of the data here because they are lists with very specific characteristics for this function. I’m sorrry.

Follow the function:

df <- list()

build_HUW_raster <- function(.x, .y) {
  list.time <- .x %>%
    split(.$id) %>%
    purrr::map(~list(t=as.matrix(.x$date),
                     xy=unname(as.matrix(.x[,c(22,23)])))
    )
 
  for(i in 1:50){
    cat(i," ")
    path=list.time[[i]]
    ctmc=ctmcmove::path2ctmc(path$xy,path$t,r,method="LinearInterp")
    df[[i]] <- as.data.frame(do.call(cbind, ctmc))
  }
 
  df <-  df %>% purrr::map(~ group_by(., ec) %>%
                             summarise(rt = mean(rt)) %>%
                             arrange(desc(rt))
  )
 
  stacktime <- df %>% purrr::map(~ rename(., cell = ec)) %>%
    map(~dplyr::left_join(cargo.grid, ., by="cell", copy=T)) %>%
    map(~raster::rasterize(., r, field="rt", na.rm=F, background=0)) %>%
    raster::stack()
 
  stackprop <- .y %>%
    split(.$id) %>%
    purrr::map(~ raster::rasterize(., y = r,
                                   field=.$proportion,
                                   fun=function(x, ...)median(x))) %>%
                 raster::stack()
   
  stack_huw <- raster::overlay(raster::calc(stacktime, fun=function(x)
      ifelse(is.na(x), NA, x/sum(x, na.rm=T))), stackprop, fun=function(x,y)x*y
      )
 
      raster_mean <- raster::stackApply(stack_huw,
      indices = rep(1,raster::nlayers(stack_huw)),
      fun = "mean",
      na.rm = F
  )
}

result.list <- purrr::map2 (.x=list1, .y=list2, fun=build_HUW_raster)

>Solution :

The reason is based on the element looped. [[ extracts the list element and depending on the class of the element, map loops over either individual elements if it is a vector/matrix or the columns in case of data.frame as these are units. By using [, it extracts the element as a list

list(1, 2, 3)[1]
[[1]]
[1] 1

vs

list(1, 2, 3)[[1]]
[1] 1

When we loop over map and apply some functions that require a specific structure i.e. colSums require a matrix/data.frame ie. with dim attributes, it fails if we use [[

> map(replicate(2,  data.frame(col1 = 1:5, col2 = 6:10), simplify = FALSE)[[1]], colSums)
Error in .f(.x[[i]], ...) : 
  'x' must be an array of at least two dimensions
> map(replicate(2,  data.frame(col1 = 1:5, col2 = 6:10), simplify = FALSE)[1], colSums)
[[1]]
col1 col2 
  15   40 

Here, we may change the code to

purrr::map2(.x=list1[1], .y=list2[1], fun=build_HUW_raster)

Leave a ReplyCancel reply