rlapplyinext

lapply Question: How to streamline further without generating errors


I'm looking to condense the steps in my script, but I'm having issues with lapply(). It looks to be an issue with my code as usual. Any help would be much appreciated!

library(iNEXT)

sa4 <- list(Bird = list(structure(c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 
1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 
0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 
0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 
0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0), .Dim = c(26L, 
6L), .Dimnames = list(Scientific_name = c(" Pycnonotus plumosus", 
"Acridotheres javanicus", "Aegithina tiphia", "Aethopyga siparaja", 
"Anthreptes malacensis", "Aplonis panayensis", "Cacatua goffiniana", 
"Callosciurus notatus", "Cinnyris jugularis", "Copsychus malabaricus", 
"Copsychus saularis", "Dicaeum cruentatum", "Dicrurus paradiseus", 
"Gorsachius melanolophus", "Larvivora cyane", "Macronus gularis", 
"Oriolus chinensis", "Orthotomus atrogularis", "Otus lempiji", 
"Pitta moluccensis", "Pycnonotus goiavier", "Pycnonotus plumosus", 
"Pycnonotus zeylanicus", "Spilopelia chinensis", "Todiramphus chloris", 
"Zosterops simplex"), Sampling_Point = c("SA_01", "SA_02", "SA_03", 
"SA_04", "SA_05", "SA_06")))), Butterfly = list(structure(c(0, 
0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 
0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0), .Dim = c(10L, 
4L), .Dimnames = list(Scientific_name = c("Burara harisa consobrina", 
"Catopsilia pyranthe pyranthe", "Catopsilia scylla cornelia", 
"Delias hyparete metarete", "Eurema sp", "Idea leuconoe clara", 
"Pachliopta aristolochiae asteris", "Phalanta phalantha phalantha", 
"Troides helena cerberus", "Zizula hylax pygmaea"), Sampling_Point = c("SA_01", 
"SA_02", "SA_04", "SA_06")))), Mammal = list(structure(c(0, 1, 
1, 1, 1, 0), .Dim = 2:3, .Dimnames = list(Scientific_name = c("Callosciurus notatus", 
"Unidentified Fruit Bat sp"), Sampling_Point = c("SA_03", "SA_04", 
"SA_05")))), Reptile = list(structure(1, .Dim = c(1L, 1L), .Dimnames = list(
    Scientific_name = "Hemidactylus frenatus", Sampling_Point = "SA_05"))))

I've been doing it the longer way:

estimateD(sa4$Butterfly, datatype="incidence_raw") #Sampling coverage for butterflies
estimateD(sa4$Mammal, datatype="incidence_raw") #Sampling coverage for mammals
estimateD(sa4$Bird, datatype="incidence_raw") #Sampling coverage for birds
estimateD(sa4$Reptile, datatype="incidence_raw") #Sampling coverage for reptiles

Note that estimateD(sa4$Reptile, datatype="incidence_raw" generates an error since it only has one species.

Is it possible to condense the following steps via lapply? In this situation I've only have 4 taxa, but for other projects, it might be a lot more. I tried the following and it gives me a warning message--which actually is the same warning message as the one above. I'm wondering if lapply stops working if one component gives an error?

> (lapply(sa4, function(x) estimateD(x, datatype="incidence_raw")) )
Error in `[.data.frame`(tmp, , c(1, 2, 3, 7, 4, 5, 6)) : 
  undefined columns selected
In addition: Warning messages:
1: In FUN(X[[i]], ...) :
  Invalid data type, the element of species by sites presence-absence matrix should be 0 or 1. Set nonzero elements as 1.
2: In log(b/Ub) : NaNs produced

Please let me know if I need to provide more information? Thank you!


Solution

  • This is a simple error trapping issue. Wrap tryCatcharound your problem function call and have the error function return information on what happened.

    results <- lapply(sa4, function(x) {
      tryCatch(estimateD(x, datatype="incidence_raw"),
               error = function(e) e) 
    })
    

    Now determine which ran alright.

    ok <- !sapply(results, inherits, "error")
    ok
    #   Bird Butterfly    Mammal   Reptile 
    #   TRUE      TRUE      TRUE     FALSE
    

    And check those that did.

    results[ok]