0

When applying a function to each element of a list using l_ply, how can I generate an output showing me the number of the element of the list the function is momentarily applied to? It's similar to a progress bar (l_dply(list, function, .progress = progress_text(char = '*')), but what I'd like is an indicator of the position of the element in the list currently being processed by the function.

For example, if my list has 100 elements, I would like output from 1 to 100 for each iteration the function is applied.

I am using l_ply with a downloader function, so my ultimate goal is to be able to find out for which list element the download did not work.

Hendrik
  • 321
  • 1
  • 14
  • Not sure it would be the best way to do it. You should look at http://r4ds.had.co.nz/iteration.html#dealing-with-failure. – F. Privé Sep 06 '17 at 08:58
  • Something like this? https://stackoverflow.com/questions/9950144/access-lapply-index-names-inside-fun If I need anything like that, I usually resort to a for loop or `mapply` where one variable is a list of "iterators" and the second one is actually the things I'm trying to process. Oh, and here's the solution mentioned by Ana: https://stackoverflow.com/a/29833989/322912 – Roman Luštrik Sep 06 '17 at 09:31

1 Answers1

1

Maybe this would work for you:

l_ply2<- function(.data, .fun = NULL, ..., .progress = "none", .inform = FALSE,
                   .print = FALSE, .parallel = FALSE, .paropts = NULL){
  i <- 0
  fun2 <- function(x){
    i <<- i+1
    print(i)
    .fun(x)
  }
  plyr::l_ply(.data, fun2, ..., .progress = .progress, .inform = .inform,
         .print = .print, .parallel = .parallel, .paropts = .paropts)
}

l_ply2(list("a","b","c"),print)
# [1] 1
# [1] "a"
# [1] 2
# [1] "b"
# [1] 3
# [1] "c"

EDIT:

I fixed it to work with ellipsis (...), it's ugly though, the kind of ugly that usually gets me downvotes :), anyway here goes, and if you can, help me make it beautiful:

l_ply2<- function(.data, .fun = NULL, ..., .progress = "none", .inform = FALSE,
                   .print = FALSE, .parallel = FALSE, .paropts = NULL){
  i <- 0
  str <- paste0(deparse(args(.fun))[1],
                "{i<<-i+1;print(i);",
                as.character(substitute(.fun)),
                "(",paste(paste(formalArgs(.fun),"=",formalArgs(.fun)),collapse=","),")}")
  fun2 <- eval(parse(text = str))
  plyr::l_ply(.data, fun2, ..., .progress = .progress, .inform = .inform,
         .print = .print, .parallel = .parallel, .paropts = .paropts)
}

l_ply2(list("a","b","c",123.456),print,digits=4)
# [1] 1
# [1] "a"
# [1] 2
# [1] "b"
# [1] 3
# [1] "c"
# [1] 4
# [1] 123.5
moodymudskipper
  • 46,417
  • 11
  • 121
  • 167