Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get R list column names from C code

Tags:

c++

r

I need to write a C/C++ function that will retrieve R list column names.

From R I want to do the following.

> dyn.load("R_list.dll")
> x = list(param1="value1", param2="value2", param3="value3")
> .Call("func", x)

and as an output I want to see "param1" "param2" "param3" as names(x) function does from R

> names(x) [1] "param1" "param2" "param3"

In my cpp file I have the following

#include <R.h>
#include <Rinternals.h>
#include <Rdefines.h>

extern "C" __declspec( dllexport ) SEXP func(SEXP list)
{
    try
    {
        if (isNewList(list))
        {
            int n = length(list);
            printf("%d\n", n);
            for (int i=0; i<n; ++i)
                printf("%s\n", CHAR(STRING_ELT(VECTOR_ELT(list, i), 0)));
        }
        else
        {
            throw std::exception("'list' variable must be a list!");
        }       
    }
    catch(const std::exception& ex)
    {
        printf("Exception was thrown: %s\n", ex.what());
    }
    return R_NilValue;
}

How to get column names, not the values, from C/C++ code?

like image 778
Samvel Hovsepyan Avatar asked Jun 05 '14 13:06

Samvel Hovsepyan


People also ask

How do I get a list of columns in R?

To find the column names and row names in an R data frame based on a condition, we can use row. names and colnames function. The condition for which we want to find the row names and column names can be defined inside these functions as shown in the below Examples.

How do I extract columns by column names in R?

To select columns in R you can use either R base df[] notation or select() function from dplyr package.

How do I get a list of variable names in R?

You can use ls() to list all variables that are created in the environment. Use ls() to display all variables. pat = " " is used for pattern matching such as ^, $, ., etc.


2 Answers

It's all there in Rf_getAttrib, R_NamesSymbol, see Writing R Extensions:

library('inline')
listnames <- cfunction(signature(x="list"), "
   return Rf_getAttrib(x, R_NamesSymbol);
")

listnames(list(param1="value1", param2="value2", param3="value3"))
## [1] "param1" "param2" "param3"

As you see, Rf_getAttrib returns an ordinary character vector here, which may be manipulated with STRING_ELT.

like image 147
gagolews Avatar answered Oct 15 '22 07:10

gagolews


Even shorter -- one statement as Rcpp takes care of all the conversions.

First load Rcpp:

R> library(Rcpp)

The create our one-statement function

R> cppFunction('CharacterVector mynames(List l) { return l.attr("names"); }') 

and test it:

R> mynames(list(a=1:3, b=runif(10), c=LETTERS))
[1] "a" "b" "c"
R> 

Edit: As Romain reminded me, an even shorter variant is using names():

R> cppFunction('CharacterVector mynames(List l) { return l.names(); }') 
R> mynames(list(a=1:3, b=runif(10), c=LETTERS))
[1] "a" "b" "c"
R> 
like image 26
Dirk Eddelbuettel Avatar answered Oct 15 '22 08:10

Dirk Eddelbuettel