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?
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.
To select columns in R you can use either R base df[] notation or select() function from dplyr package.
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.
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
.
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With