我需要编写一个C / C ++函数来检索R列列名。
从R我想做以下事情。
> dyn.load("R_list.dll")
> x = list(param1="value1", param2="value2", param3="value3")
> .Call("func", x)
作为输出我希望看到"param1" "param2" "param3"
作为names(x)
函数来自R
> names(x)
[1] "param1" "param2" "param3"
在我的cpp文件中,我有以下
#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;
}
如何从C / C ++代码中获取列名而不是值?
答案 0 :(得分:8)
全部位于Rf_getAttrib
,R_NamesSymbol
,见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"
如您所见,Rf_getAttrib
在此返回一个普通的字符向量,可以使用STRING_ELT
进行操作。
答案 1 :(得分:2)
更短 - 一个声明,因为Rcpp负责所有的转换。
首先加载Rcpp:
R> library(Rcpp)
创建我们的单语句函数
R> cppFunction('CharacterVector mynames(List l) { return l.attr("names"); }')
并测试它:
R> mynames(list(a=1:3, b=runif(10), c=LETTERS))
[1] "a" "b" "c"
R>
编辑:正如Romain提醒我的,更短的变体是使用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>
答案 2 :(得分:1)
attr
成员函数也可以用于此(虽然@gagolews的回答显然更简单):
require(inline)
l <- list(a=1:3, b=runif(10))
f <- cxxfunction(signature(x_ = "List"), plugin = "Rcpp", body = '
Rcpp::List x(x_);
CharacterVector names = x.attr("names");
return names;
')
f(l)
# [1] "a" "b"