Search code examples
rfunctiondataframelapplymapply

Extracting conditional rows from a list of dataframes in a loop


In my split(w7, w7$study.name)[48] call below there are 4 rows for which variable control == FALSE.

But I'm wondering why ctlistG(split(w7, w7$study.name)[48]) returns only one of such rows?

ps. I suspect, instead of lapply() I should have used mapply() in ctlistG().

Reproducible R code:

ctlist <- function(List, cont=FALSE, pos=1, outcom=1){

 if(!inherits(List, "list")) List <- list(List)  
  
h <- setNames(lapply(List, function(i) i[i$control==cont & i$post == pos & i$outcome == outcom, , drop = FALSE]), names(List)) 

Filter(NROW, h) }

#====================

ctlistG <- function(m){
  
  input <- setNames(lapply(m, function(i) rev(expand.grid(outcom = seq_len(max(i$outcome, na.rm = TRUE)), pos = seq_len(max(i$post, na.rm = TRUE))))), names(m))
  
  lapply(input, function(i) ctlist(m, cont = FALSE, pos = i$pos, outcom = i$outcom))   }

#==================== EXAMPLE OF USE:
w7 <- read.csv('https://raw.githubusercontent.com/rnorouzian/m/master/w7.csv')

ctlistG(split(w7, w7$study.name)[48])  # I expect 4 rows not 1 below!

#$VanBe_Jng_KenA
#$VanBe_Jng_KenA$VanBe_Jng_KenA
#        study.name YofPub group.name  n  d
#406 VanBe_Jng_KenA   2012         NA 34 NA 

Solution

  • If we need 4 rows, based on the function, we may need Map instead of lapply

    out <- do.call(rbind, lapply(input, function(inp) 
          do.call(rbind, Map(function(p, o)
       do.call(rbind, lapply(m, function(m1)
        m1[m1$control == FALSE & m1$post == p & m1$outcome ==o, , drop = FALSE])),
          inp$pos, inp$outcom))))
    

    data

    lst1 <- split(w7, w7$study.name)
    m <- lst1[48]