Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

index/position to find result from list.search in original list #104

Open
timelyportfolio opened this issue Apr 10, 2015 · 6 comments
Open

Comments

@timelyportfolio
Copy link
Contributor

Is there a mechanism to retrieve the index/position from a list.search result? As an example, let's use a good old dendrogram. Most of the important meta information for a dendrogram is stored in attributes.

dh <- as.dendrogram(hclust(dist(USArrests), "ave"))
rapply(dh,attributes,how="list")

If we wanted to find the node labelled Alabama, we could do something like this.

dl_search <- list.search(dh,any(attributes(.)=="Alabama"))

Now, is there any way to take the result which I called dl_search to get this item in the original list? I found this, but I was hoping for something more elegant. With the changes introduced in befdb80, I think it really becomes impossible.

@timelyportfolio timelyportfolio changed the title index to find result from list.search in original list index/position to find result from list.search in original list Apr 10, 2015
@renkun-ken
Copy link
Owner

What is the expected result you're trying to get, @timelyportfolio?

@timelyportfolio
Copy link
Contributor Author

Well, some kind of path or pointer to the item where the search returns TRUE. In the example above, for Alabama, I know through inspection that the path is.

dh <- as.dendrogram(hclust(dist(USArrests), "ave"))
dh[[1]][[2]][[2]][[1]][[1]][[2]][[1]]
# or this also works
dh[[c(1,2,2,1,1,2,1)]]

However, I do not know of a way in R with rlist or any other package to easily give me that information.

@renkun-ken
Copy link
Owner

rlist::list.search uses rapply internally, the function does not provide access to the index or name of the nested list elements. A reimplementation of rapply may work.

@timelyportfolio
Copy link
Contributor Author

Ok that was my impression. I just wanted to make I sure I did not miss it. I have a local function that sort of works but needs some iteration. Thanks for confirming.

@renkun-ken
Copy link
Owner

I implement a simple list.query that recursively performs filtering and mapping on nested levels of a list.

list.query <- function(x, 
  filter = function(x, i, name) TRUE,
  map = function(x, i, name) x,
  parent.i = integer(), parent.names = character(), 
  results = new.env(parent = emptyenv()),
  convert = TRUE) {
  if (is.list(x)) {
    .mapply(function(x, i, name) {
      i <- c(parent.i, i)
      name <- c(parent.names, name)
      if (filter(x, i, name)) {
        results[[as.character(length(results) + 1L)]] <- map(x, i, name)
      }
      list.query(x, filter, map, 
        parent.i = i, parent.names = name, results = results, convert = FALSE)
    }, list(x, seq_along(x), if (is.null(names <- names(x))) "" else names), NULL)
  }
  if (convert) unname(as.list.environment(results))
}

Each time filter(...) returns TRUE, the element will be transformed by map(...). Note that the function signature should be function (x, i, name) in which x is the element being examined, i can be, for example, c(1, 3, 5) meaning the first element in 1st level, 3rd in 2nd level, 5th in 3rd level, as the index position of the element in the list, and name can be, for example, c("p1", "lang", "python") as the named position of the element in the list.

Some query might be possible to help building the filter and map function.

@renkun-ken
Copy link
Owner

Using this function, the dh case can be solved with

dh <- as.dendrogram(hclust(dist(USArrests), "ave"))
list.query(dh, filter = function(x, i, name) {
  label <- attr(x, "label") 
  !is.null(label) && label == "Alabama"
}, map = function(x, i, name) {
  list(x = x, i = i)
})
[[1]]
[[1]]$x
'dendrogram' leaf 'Alabama', at height 0 

[[1]]$i
[1] 1 2 2 1 1 2 1

The result set include both the object and its indexed position.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants