【问题标题】:Rcpp::DataFrame::create is limited by 20 arguments? [duplicate]Rcpp::DataFrame::create 受限于 20 个参数? [复制]
【发布时间】:2018-02-27 08:49:46
【问题描述】:

我们在 Rcpp 函数中创建以下数据框:

  Rcpp::DataFrame res =
    Rcpp::DataFrame::create(
     Rcpp::Named("A")=a
    ,Rcpp::Named("B")=b
    ,Rcpp::Named("C")=c
    ,Rcpp::Named("D")=d
    ,Rcpp::Named("E")=e
    ,Rcpp::Named("F")=f
    ,Rcpp::Named("G")=g
    ,Rcpp::Named("H")=h
    ,Rcpp::Named("I")=i
    ,Rcpp::Named("J")=j
    ,Rcpp::Named("K")=k
    ,Rcpp::Named("L")=l
    ,Rcpp::Named("M")=m
    ,Rcpp::Named("N")=n
    ,Rcpp::Named("O")=o
    ,Rcpp::Named("P")=p
    ,Rcpp::Named("Q")=q
    ,Rcpp::Named("R")=r
    ,Rcpp::Named("S")=s
    ,Rcpp::Named("T")=t
    ,Rcpp::Named("U")=u
  );

此数据框旨在作为返回的结果。但是由于以下错误无法编译:

error: no matching function for call to Rcpp::DataFrame_Impl<Rcpp::PreserveStorage>::create
In file included from local/lib64/R/library/Rcpp/include/Rcpp/DataFrame.h:97:0,
                 from local/lib64/R/library/Rcpp/include/Rcpp.h:57,
                 from file54f121e6a937.cpp:1:
local/lib64/R/library/Rcpp/include/Rcpp/generated/DataFrame_generated.h:142:23: note: template<class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15, class T16, class T17, class T18, class T19, class T20> static Rcpp::DataFrame_Impl<StoragePolicy> Rcpp::DataFrame_Impl<StoragePolicy>::create(const T1&, const T2&, const T3&, const T4&, const T5&, const T6&, const T7&, const T8&, const T9&, const T10&, const T11&, const T12&, const T13&, const T14&, const T15&, const T16&, const T17&, const T18&, const T19&, const T20&) [with T1 = T1; T2 = T2; T3 = T3; T4 = T4; T5 = T5; T6 = T6; T7 = T7; T8 = T8; T9 = T9; T10 = T10; T11 = T11; T12 = T12; T13 = T13; T14 = T14; T15 = T15; T16 = T16; T17 = T17; T18 = T18; T19 = T19; T20 = T20; StoragePolicy = Rcpp::PreserveStorage]
 static DataFrame_Impl create( const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6, const T7& t7, const T8& t8, const T9& t9, const T10& t10, const T11& t11, const T12& t12, const T13& t13, const T14& t14, const T15& t15, const T16& t16, const T17& t17, const T18& t18, const T19& t19, const T20& t20 ) {
                       ^
local/lib64/R/library/Rcpp/include/Rcpp/generated/DataFrame_generated.h:142:23: note:   template argument deduction/substitution failed:
file54f121e6a937.cpp:771:7: note:   candidate expects 20 arguments, 21 provided

它适用于 20 个参数。我们如何克服这个问题?谢谢

【问题讨论】:

  • 本质上是一个常见问题解答。如果您需要超过 20 列,请将它们嵌套在一个列表对象中,该元素最多使用 20 列。
  • @Dirk Eddelbuettel。谢谢你。 Rcpp::List::create 是否也有 20 个限制?如果是这样,那么上限为 20x20 = 400?
  • 是递归数据结构,所以 20 x 20 x 20 x 20 x 20 ...
  • @Dirk Eddelbuettel。谢谢你。将它推入 Rcpp 堆栈并在编译时使宏限制可由用户参数化(无论如何用户必须在每次运行时编译代码),这对用户来说不会更友好。您有编译器选择的 c++11 选项。所以,这应该没有任何问题。
  • 我们需要支持旧编译器的关键特性。但是该架构是可扩展的,因此可以轻松地贡献一个带有功能的包,以创建您想要的尽可能多的元素。

标签: r rcpp rcpp11


【解决方案1】:

是的。这在许多不同的地方都有介绍......

在我的头顶上:

https://cran.r-project.org/web/packages/Rcpp/vignettes/Rcpp-FAQ.pdf#page=17

本质上,为了能够用最多的编译器编译它,Rcpp 受到了旧版本的约束 不支持可变函数参数的 C++ 标准。所以我们实际上使用宏和代码生成器脚本来 显式枚举参数,并且该数字必须在某个限制处停止。我们选择了 20 个。


用于创建超过 20 列的data.frame 的方法是创建一个list,然后强制转换为data.frame

示例代码:

#include <Rcpp.h>

// [[Rcpp::export]]
Rcpp::List dynamic_df(Rcpp::DataFrame df) {

  // Number of variables in data.frame
  int num_vars = df.ncol();

  // Instantiate list with p variable entries
  Rcpp::List long_list(num_vars);

  // Make a variable to name columns
  Rcpp::CharacterVector namevec(num_vars);

  // Copy from data.frame into list.
  for (int i=0;i < num_vars; ++i) {
    long_list[i] = df(i); // Move vector from data frame to list
    namevec[i] = i;
  }

  // Add colnames
  long_list.attr("names") = namevec;

  // Coerce list to data.frame
  long_list.attr("row.names") = Rcpp::IntegerVector::create(NA_INTEGER, df.nrow());
  long_list.attr("class") = "data.frame";

  // Return result.. Will appear as data.frame
  return long_list;
}

/*** R

head(dynamic_df(mtcars))

*/

输出:

head(dynamic_df(mtcars))
#      0 1   2   3    4     5     6 7 8 9 10
# 1 21.0 6 160 110 3.90 2.620 16.46 0 1 4  4
# 2 21.0 6 160 110 3.90 2.875 17.02 0 1 4  4
# 3 22.8 4 108  93 3.85 2.320 18.61 1 1 4  1
# 4 21.4 6 258 110 3.08 3.215 19.44 1 0 3  1
# 5 18.7 8 360 175 3.15 3.440 17.02 0 0 3  2
# 6 18.1 6 225 105 2.76 3.460 20.22 1 0 3  1

不过,您确实应该考虑在重复条目中使用 Kevin 的 List_Builder 类。

参考

how many vectors can be added in DataFrame::create( vec1, vec2 ... )?

【讨论】:

  • 您能否提供一个“构建列表,然后强制转换为 data.frame”的示例,以便我对其进行测试?谢谢。
  • @Dimon,查看更新后的回复。
  • 谢谢。我想知道这些包装器在时间和数据复制方面的效率如何。
猜你喜欢
  • 2023-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-10
  • 1970-01-01
  • 1970-01-01
  • 2011-10-11
  • 1970-01-01
相关资源
最近更新 更多