Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find index position in nested lists for match

Tags:

list

indexing

r

I want to find the Indexes of the match of a nested list and a target value (11).

Data:

f <- list(
  list(1, 2, 3),
  list(4, 5, list(8, list(11, 12)))
)

Desired Output for target value = 11.:

c(2, 3, 2, 1)

Printed:

 f
[[1]]
[[1]][[1]]
[1] 1

[[1]][[2]]
[1] 2

[[1]][[3]]
[1] 3


[[2]]
[[2]][[1]]
[1] 4

[[2]][[2]]
[1] 5

[[2]][[3]]
[[2]][[3]][[1]]
[1] 8

[[2]][[3]][[2]]
--->>>  [[2]][[3]][[2]][[1]]  <<<----
-->>>> [1] 11 <<<----

[[2]][[3]][[2]][[2]]
[1] 12

What i tried:

match with unlist(data), Looking for Parameter in which() and Looking into arrInd().

I would avoid running multiple for loops in R. It would be better to do all loops in C, C++,... Before implementing it myself i wanted to check if i am missing a function.

like image 788
Tlatwork Avatar asked Aug 08 '19 20:08

Tlatwork


People also ask

How do I access nested list index?

You can access a nested list by negative indexing as well. Negative indexes count backward from the end of the list. So, L[-1] refers to the last item, L[-2] is the second-last, and so on.

How do you find the index of an element in a list of lists?

To find the (row, column) index pair of an element in a list of lists, iterate over the rows and their indices using the enumerate() function and use the row. index(x) method to determine the index of element x in the row .


2 Answers

foo = function(x, sep = ".") {
    names(x) = paste0(seq_along(x))
    while(any(sapply(x, class) == "list")) {
        ind = sapply(x, class) == "list"
        temp = unlist(x[ind], recursive = FALSE)
        names(temp) = paste0(rep(names(x)[ind], lengths(x[ind])),
                             sep,
                             sequence(lengths(x[ind])))
        x = c(x[!ind], temp)
    }
    return(x)
}
f2 = foo(f)
names(which(unlist(f2) == 11))
#[1] "2.3.2.1"
like image 111
d.b Avatar answered Sep 17 '22 17:09

d.b


This can also be done with rrapply in the rrapply-package (extended version of base rapply). The condition argument decides to which elements f should be applied, and the .xpos argument in the f function evaluates to the position of the element in the nested list. how = "flatten" discards all list elements that do not satisfy condition and returns a flattened list:

library(rrapply)

rrapply(f, condition = function(x) x == 11, f = function(x, .xpos) .xpos, how = "flatten")
#> [[1]]
#> [1] 2 3 2 1
like image 36
Joris C. Avatar answered Sep 19 '22 17:09

Joris C.