[Rcpp-devel] Help with accessing and manipulating List objects

Dirk Eddelbuettel edd at debian.org
Sat Jul 20 19:47:15 CEST 2013


Hi Tal,

And welcome!

On 20 July 2013 at 19:44, Tal Galili wrote:
| Hello dear Rcpp users,
| 
| First - I'd like to say that I took Hadley and Romain's workshop at the useR
| conference this year, and I am very excited about trying out Rcpp - this
| project looks AMAZING.

Your feedback (as conveyed earlier in private email) is much appreciated.

There was a second, and also very positive, response to the same workshop:
Joe posted it on the REvo blog last week---somehow that never made it through
R Bloggers, I think.

| Second - this is my first post, and I apologize if my question is too basic. To
| my defense, I tried looking through this mailing list / googled before asking,
| and read through Hadley's github chapter on Rcpp.

I hear there is a book on Rcpp too :)
 
| The questions:
| 
| I am looking to understand better how List objects can be navigated, their
| elements accessed, and manipulated - using Rcpp.
| 
| For example, here is an R list object:
| 
| x <- list(a = 1, b = 2, c = list(ca = 3, cb = 4, 5), 6)
| attr(x[[1]], "type") = "fun"
| attr(x[[3]][[1]], "type") = "fun"
| x
| 
| I would like to create two types of functions:
| 1) A function that will go through "x" and will RETURN all of the elements
| within it that are of type "fun".
| In R I would do it like this:
| 
| return_fun <- function(x) {
|    fun_nubmers <- numeric()
|    for(i in seq_along(x)) {      
|       if(class(x[[i]]) == "list") {
|          fun_nubmers <- c(fun_nubmers, return_fun(x[[i]]))
|       } else {
|          if(!is.null(attr(x[[i]], "type"))) {
|             if(attr(x[[i]], "type") == "fun") fun_nubmers <- c(fun_nubmers, x
| [[i]])   
|          }         
|       }
|    }
|    return fun_nubmers
| }
| return_fun(x) # output: 1 3
| 
| But in Rcpp there are many parts to this R function that I don't know how to
| do. I don't know how to access the attributes of a sub-element within a List, I
| don't know how to check if that attribute is null or not, etc. So any
| suggestions on either reading material (or better yet - an example of how this
| function might be created in Rcpp would be great.

You can access attributes, pretty much as in R.  You can access lists within
lists, pretty much as in R.

Two quick pointers to working examples:

  -- our unit tests, especially now that they all have been rewritten via
     Rcpp attributes to be R files calling sourceCpp on C++ files:

     edd at max:~$ grep -l attr /usr/local/lib/R/site-library/Rcpp/unitTests/cpp/*
     /usr/local/lib/R/site-library/Rcpp/unitTests/cpp/DataFrame.cpp
     /usr/local/lib/R/site-library/Rcpp/unitTests/cpp/S4.cpp
     edd at max:~$ 

  -- the Rcpp Gallery which has several posts on attr

Likewise, Lists within lists can be accessed as well. You need to test each
element for its type. The Rcpp Gallery has a 'dispatch on type' example as I
recall. These still use the C API of R --- but Romain just added beginnings
of is<foo>(x) tests to Rcpp's SVN which will help with tasks like this.
 
| 2) A function that will go through "x" and will CHANGE all of the elements
| within it that are of type "fun". For example, adding 1 to them.
| In R I would do it like this:
| 
| add1_fun <- function(x) {
|    for(i in seq_along(x)) {      
|       if(class(x[[i]]) == "list") {
|          x[[i]] <- add1_fun(x[[i]])
|       } else {
|          if(!is.null(attr(x[[i]], "type"))) {
|             if(attr(x[[i]], "type") == "fun") x[[i]] <- x[[i]] + 1
|          }         
|       }
|    }
|    x
| }
| add1_fun(x) 
| return_fun(x) # output: 1 3 
| return_fun(add1_fun(x) ) # output: 2 4 

That is similar -- you need to test and recurse as well.
 
| 3) Is it possible to work with some "global" variable from within a recursive
| Rcpp function?
| For example:
| 
| 
| count_till_5 <- function() {
|    if(!exists("global_var")) global_var = 0 
| 
|    if(global_var <5) {
|       global_var <<- global_var+1
|       count_till_5()
|    }   
| }
| count_till_5()
| global_var
| 
| Is there a way to create something like this with Rcpp?

Yes by using the Environment class and accessing elements from a given
environment -- here the global one.
 
Again, I think the Rcpp Gallery has a Environment example. The unit tests do.

These are all nice yet not entirely trivial questions. I would like try to
cook something up (unless somebody beats me to it) but I have a things I need
to be working on instead ...   

Cheers, Dirk
 
-- 
Dirk Eddelbuettel | edd at debian.org | http://dirk.eddelbuettel.com


More information about the Rcpp-devel mailing list