c++ - Rcpp 创建具有可变列数的 DataFrame

标签 c++ r rcpp

我对使用 Rcpp 创建列数可变的数据框很感兴趣。也就是说,我的意思是列数只有在运行时才知道。有些列是标准列,但其他列将重复 n 次,其中 n 是我在特定运行中考虑的特征数。

我知道我可以按如下方式创建数据框:

IntegerVector i1(3); i1[0]=4;i1[1]=2134;i1[2]=3453;
IntegerVector i2(3); i2[0]=4123;i2[1]=343;i2[2]=99123;
DataFrame df = DataFrame::create(Named("V1")=i1,Named("V2")=i2);

但在这种情况下,假定列数为 2。

为了简化我需要的解释,假设我想传递一个 SEXP 变量,指定要在变量部分创建的列数。像这样的东西:

RcppExport SEXP myFunc(SEXP n, SEXP <other stuff>)
IntegerVector i1(3); <compute i1>
IntegerVector i2(3); <compute i2>
for(int i=0;i<n;i++){compute vi}
DataFrame df = DataFrame::create(Named("Num")=i1,Named("ID")=i2,...,other columns v1 to vn);

其中 n 作为参数传递。 R 中的最终数据框看起来像

Num ID V1 ... Vn
  1  2  5     'aasda'
  ...

(实际上,列名不会是“Vx”的形式,但它们在运行时是已知的。)换句话说,我不能使用静态列表

Named()=...

因为数字会改变。

我尝试跳过构造函数的“Named()”部分,然后在末尾命名列,但结果是垃圾。

这可以做到吗?

最佳答案

如果我正确理解了你的问题,那么利用 DataFrame 构造函数似乎是最简单的,它以 List 作为参数(因为List 可以直接指定),并通过 .attr("names")CharacterVector 设置列的名称:


#include <Rcpp.h>

// [[Rcpp::export]]
Rcpp::DataFrame myFunc(int n, Rcpp::List lst, 
                       Rcpp::CharacterVector Names = Rcpp::CharacterVector::create()) {

  Rcpp::List tmp(n + 2);
  tmp[0] = Rcpp::IntegerVector(3);
  tmp[1] = Rcpp::IntegerVector(3);

  Rcpp::CharacterVector lnames = Names.size() < lst.size() ?
    lst.attr("names") : Names;
  Rcpp::CharacterVector names(n + 2);
  names[0] = "Num";
  names[1] = "ID";

  for (std::size_t i = 0; i < n; i++) {
    // tmp[i + 2] = do_something(lst[i]);
    tmp[i + 2] = lst[i];
    if (std::string(lnames[i]).compare("") != 0) {
      names[i + 2] = lnames[i];
    } else {
      names[i + 2] = "V" + std::to_string(i);
    }
  }
  Rcpp::DataFrame result(tmp);
  result.attr("names") = names;
  return result;
}

还有一些额外的事情可以让 Names vector 是可选的——例如如果您只使用命名列表,则可以省略第三个参数。


lst1 <- list(1L:3L, 1:3 + .25, letters[1:3])
##
> myFunc(length(lst1), lst1, c("V1", "V2", "V3"))
#  Num ID V1   V2 V3
#1   0  0  1 1.25  a
#2   0  0  2 2.25  b
#3   0  0  3 3.25  c

lst2 <- list(
  Column1 = 1L:3L,
  Column2 = 1:3 + .25,
  Column3 = letters[1:3],
  Column4 = LETTERS[1:3])
##
> myFunc(length(lst2), lst2)
#  Num ID Column1 Column2 Column3 Column4
#1   0  0       1    1.25       a       A
#2   0  0       2    2.25       b       B
#3   0  0       3    3.25       c       C

请注意 this signature 的 20 长度限制DataFrame 构造函数,正如@hrbrmstr 所指出的。

关于c++ - Rcpp 创建具有可变列数的 DataFrame,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32060019/

相关文章:

c++ - 我如何解决 : "error C2039: ' {ctor }' : is not a member of" in Visual Studio 2005?

r - 带有 NULL 参数的 Julia 函数

r - 编织时保持R Notebook表格格式

r - 如何在 R 中为大型数据框使用字典?

c++ - RCpp:期待单值错误

java - WinCrypt RSA 与 Java org.bouncycaSTLe

c++ - 使用GDB查找某个函数对应的内存地址/调试

c++ - 问题 : 2d Vector (nested Vector) with datatype of new class

r - 将 char* 转换为 SEXP

r - 在 Rcpp 中 - 如何返回带有名称的向量