在 Rcpp List 中向元素追加内容

5
可能是一个愚蠢的问题,但我已经寻找答案很久了,但没有找到:
我正在尝试编写一个文件阅读器,类似于freadread.delim,但是用C++实现,并通过Rcpp连接到R。最简单的方法是让它输出一个向量List - 每个列一个 - 并将类设置为data.frame
List foo;
foo.push_back(column);
foo.attr("class") = "data.frame";
return foo;

很简单,我以前做过。不幸的是:

  1. 我要读取的文件可以有不同数量的字段;
  2. 如果您按列读取文件,则此模型只能优雅地工作,而实际文件倾向于按行读取。

因此,答案是能够定义foo,然后对于每个读入的行,将一个字段推入foo的底层向量中的每个字段push_back():

List foo(1);
foo[0].push_back("turnip");

很遗憾,我无法解决这个问题:似乎无法将列表的成员向量推入push_back(),因为这会导致错误“Rcpp::Vector<19>::Proxy没有名为push_back()的成员”。
因此,我的问题是:是否有任何方法可以在Rcpp列表中附加到向量?或者我的唯一选择是逐列读取文件,将结果向量附加到“foo”,并咬住性能成本,这将导致必须迭代[列数]次而不是一次?
希望这个问题足够清楚。乐意回答任何问题。
1个回答

5

当你事先不知道行或列时,这是一个半难的问题。

在几年前的一个关闭项目中,我将我的数据收集为变体类型(使用相应的Boost类),并在最后进行转换。

Rblpapi中(我贡献了一些其他代码),Whit尝试了几种方法,并最终定义了自己的帮助函数,我一直想提炼/重构它并与Kevin讨论--但这还没有发生。

因此,请随意提出更好的解决方案 :)

总的来说,回到你的问题上,我们经常以逐行方式接收数据,通常通过回调。当您逐个元素添加时,Rcpp类型(包装R类型)表现非常糟糕--因此不要进行天真的push_back,因为您将会复制很多。因此,如果您知道您的类型,请对应使用std::list和相应的std::vector<T>。这些向量可以增长。一旦您拥有它们,组装一个Rcpp::List,因此Rcpp::DataFrame更容易。


1
有道理。那么总结一下,即使看起来效率低下,最有效的方法可能是反复迭代文件,依次提取每个列作为std::vector,然后将该向量整体添加到列表中? - Oliver Keyes
1
在许多情况下,您可以按行阅读,增加数据结构并在最后进行转换。但是,要完全实现通常和高效的操作是很困难的。 - Dirk Eddelbuettel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接