我按照这个链接
Passing a data frame from-to R and C using .call()
找到访问C内部R数据帧的方法。 我的要求与此相反。我在C中有一个表格数据,需要在C中创建一个R数据框对象,并将其作为SEXP返回。
对于简单的R矢量和列表创建,我按照此链接中的内容进行了操作
http://adv-r.had.co.nz/C-interface.html
但我仍然想知道如何创建一个数据帧并从C返回到R.考虑到数据帧是一个列表,我尝试创建一个列表并将其传递给它,但它预计会在R中获取一个列表而不是数据帧。
任何帮助都将不胜感激。
答案 0 :(得分:11)
您可以利用data.frame
对象是由原子向量组成的列表这一事实,每个原子向量具有相同的长度,names
,class
和row.names
属性设置正确:
library(inline)
f <- cxxfunction(signature(), body="
SEXP ret, ans1, ans2, cls, nam, rownam;
PROTECT(ret = Rf_allocVector(VECSXP, 2)); // a list with two elements
PROTECT(ans1 = Rf_allocVector(INTSXP, 3)); // first column
PROTECT(ans2 = Rf_allocVector(INTSXP, 3)); // second column
for (int i=0; i<3; ++i) { // some data
INTEGER(ans1)[i] = i+1;
INTEGER(ans2)[i] = -(i+1);
}
SET_VECTOR_ELT(ret, 0, ans1);
SET_VECTOR_ELT(ret, 1, ans2);
PROTECT(cls = allocVector(STRSXP, 1)); // class attribute
SET_STRING_ELT(cls, 0, mkChar(\"data.frame\"));
classgets(ret, cls);
PROTECT(nam = allocVector(STRSXP, 2)); // names attribute (column names)
SET_STRING_ELT(nam, 0, mkChar(\"a\"));
SET_STRING_ELT(nam, 1, mkChar(\"b\"));
namesgets(ret, nam);
PROTECT(rownam = allocVector(STRSXP, 3)); // row.names attribute
SET_STRING_ELT(rownam, 0, mkChar(\"1\"));
SET_STRING_ELT(rownam, 1, mkChar(\"2\"));
SET_STRING_ELT(rownam, 2, mkChar(\"3\"));
setAttrib(ret, R_RowNamesSymbol, rownam);
UNPROTECT(6);
return ret;
")
给出了:
print(f())
## a b
## 1 1 -1
## 2 2 -2
## 3 3 -3
答案 1 :(得分:4)
强制性Rcpp示例:
// [[Rcpp::export]]
DataFrame createTwo(){
IntegerVector v = IntegerVector::create(1,2,3);
std::vector<std::string> s(3);
s[0] = "a";
s[1] = "b";
s[2] = "c";
return DataFrame::create(Named("a")=v, Named("b")=s);
}
它将为您提供一个带有一个char矢量和一个int矢量的3x2 data.frame。