Home > Software design >  Apply list-specific cutoff value to individual vectors in nested list
Apply list-specific cutoff value to individual vectors in nested list

Time:03-22

I have a nested list, have_list. At the center is a list with four vectors of integers, a, b, c, d.

For a, b, c, d, each has a unique cutoff value. I would like to find the first positions when the integer is greater than the relevant cutoff value.

I can do this if a-d had the same cutoff by:

rapply(have_list, function(x) which.max(x > cutoff), how = "list")

My specific question is how to use the respective cutoff values for a-d, without for loops, if possible. I can't seem to find anything on the internet or SO, though apologies if I overlooked a previous question.

Sample data

cutoff <- c(a = 5, b = 17, c = 11, d = 7)

set.seed(05062020)
have_list <- list(Outer1 = list(a = sample(1:25, 10),
                                b = sample(1:25, 10),
                                c = sample(1:25, 10),
                                d = sample(1:25, 10)),
                  Outer2 = list(a = sample(1:25, 10),
                                b = sample(1:25, 10),
                                c = sample(1:25, 10),
                                d = sample(1:25, 10)))

Desired data

want_list <- list(Outer1 = list(a = 2, b = 2, c = 1, d = 1),
                  Outer2 = list(a = 1, b = 4, c = 4, d = 1))

CodePudding user response:

You can use lapply to move through the "Outer" lists, and Map to compare each inner list to the corresponding cutoff:

lapply(have_list, \(x) {Map(\(lst, cuts) {
  return(which(lst > cuts)[1])
}, x, cutoff)})

Here is the str of this output:

List of 2
 $ Outer1:List of 4
  ..$ a: int 2
  ..$ b: int 2
  ..$ c: int 1
  ..$ d: int 1
 $ Outer2:List of 4
  ..$ a: int 1
  ..$ b: int 4
  ..$ c: int 4
  ..$ d: int 1

CodePudding user response:

How about something like this:

lapply(have_list, function(x) {
  as.list(sapply(names(x), function(y) {
    min(which(x[[y]]>cutoff[[y]]))
  }))
})

Output:

$Outer1
$Outer1$a
[1] 2

$Outer1$b
[1] 2

$Outer1$c
[1] 1

$Outer1$d
[1] 1


$Outer2
$Outer2$a
[1] 1

$Outer2$b
[1] 4

$Outer2$c
[1] 4

$Outer2$d
[1] 1
  • Related