Conditionally select element positions of objects in list and return new list with object element positions

Viewed 61

I have a list of many objects; in the case of this MWE - only 6. I am interested in selecting the position of an element for objects msfr, msfl, mshr and mshl which correspond to the respective value in vms (this object holds the maximum value of the elements in the 'ms...' objects) and where scheduled.day corresponds with `day. My objective is to return a second list of objects (the 'ms...' objects) holding the position of the elements where the conditions are true. Here is the data:

l <- list(msfr=c(1,5,0,0,0),
          msfl=c(1,4,0,5,0),
          mshr=c(1,0,0,0,0),
          mshl=c(0,0,0,0,4),
          vms= c(1,5,0,5,4),
          scheduled.day = c(0, 3, 0, 4, 3)) 
today <- 3
ctt<- which(l[["scheduled.day"]] == today)

The closest I have come to achieving my objective is with the following code. But by using %in% element positions are being returned for the object msfl.

obj.names <-  names(l)[1:4]
l2 <- lapply(lapply(l[obj.names],"["), function(x){which(x %in% l[["vms"]][ctt])}) # ctt being ignored

> l2
$msfr
[1] 2

$msfl
[1] 2 4

$mshr
integer(0)

$mshl
[1] 5

What I am looking for is some neat code that will return a list that looks like this.

l3 <- list(msfr = 2,
           mshl = 5)

> l3
$msfr
[1] 2

$mshl
[1] 5
2 Answers

I must be blind!

lapply(lapply(l[obj.names],"["), function(x){which(x == l[["vms"]] & l[["scheduled.day"]] == today)})

I don't know why I didn't try this before, but it does the trick. If anyone has an alternative solution, I would be glad to see it.

Another option is to convert it to data.frame, then do a group by subset to return a summarised index and finally convert to list

library(tibble)
library(dplyr)
library(tidyr)
enframe(l[obj.names]) %>%
     unnest(c(value)) %>%
     group_by(name) %>% 
     summarise(rn = list(row_number()[value ==l[['vms']] & l[["scheduled.day"]] == today])) %>%
     unnest(c(rn)) %>%
     deframe %>% 
     as.list
#$msfr
#[1] 2

#$mshl
#[1] 5
Related