用C++编写一个Rdata文件

7
假设我有一个C++程序,其中包含一个对象向量,我想将其写入Rdata数据框文件中,每个向量元素对应一条观测记录。我该如何做呢?以下是一个示例:假设我有:
vector<Student> myStudents;

Student 是一个类,它有两个数据成员:name 类型为 std::stringgrade 类型为 int

我唯一的选择是写一个 csv 文件吗?

请注意,Rdata 是一种二进制格式,因此我想我需要使用一个库来处理它。

搜索 Rdata [r] [C++] 没有结果。


你能提供一份所需文件格式的简要示例吗? - mathematician1975
@mathematician1975 当然可以,但这是一种二进制格式(更新帖子以提及此事)。一个例子仍然有用吗? - Xu Wang
3
我认为从长远来看,你最好使用 R API 并编写 C++ 扩展。请参见 http://cran.r-project.org/doc/manuals/R-exts.html。 - user405725
@VladLazarenko 谢谢您的建议。我希望有另一种方法,但似乎没有。我使用C++来输入文件,虽然我可以从R中调用它,但这并不是最自然的方法。 - Xu Wang
1
虽然我不是一个常规的R语言用户,但你可以查看http://dirk.eddelbuettel.com/code.html,也许这里面有一些东西能帮到你。 - Ivarpoiss
1
@Ivarpoiss 谢谢。rcpp很棒。但是它在R内运行。我仍然想在R之外编写一个Rdata文件。例如,我希望我的代码可以在没有安装R的情况下使用。 - Xu Wang
3个回答

8
我认为没有人费心从R源代码中提取一个二进制文件编写器,以便独立于R使用。大约20年前,我为Octave文件做了同样的事情,因为它们的格式很简单:两个整数' n '和' k ',后跟'n * k'数据--所以你可以用两个函数调用来读/写。我担心对于R,您可能需要涵盖太多的R头文件--因此最容易的(?)路线可能是将数据传递给R,也许通过Rserve(松散连接通过tcp/ip)和RInside(通过嵌入更紧密的连接),然后由R进行编写。编辑: 在原始答案撰写之后的这些年里,已经创建了一个这样的库: librdata

1

这里是一个将列表保存为 RData 的函数示例。该示例基于之前的回答:

void save_List_RData(const List &list_Data, const CharacterVector &file_Name)
{
  Environment base("package:base");
  Environment env = new_env();
  env["list_Data"] = list_Data;
  Function save = base["save"];
  CharacterVector all(1);
  all[0] = "list_Data";
  save(Named("list", all), Named("envir", env), Named("file", file_Name));
  Rcout << "File " << file_Name << " has been saved! \\n";
}

0

我不知道这个方法是否适用于所有人的需求(那些正在谷歌这个问题的人),但是通过这种方式,您可以保存单个或多个变量:

using namespace std;
using namespace Rcpp;
using Eigen::Map; 
using Eigen::MatrixXi;
using Eigen::MatrixXd;

Environment base("package:base");

Function save = base["save"];
Function saveRDS = base["saveRDS"];

MatrixXd M = MatrixXd::Identity(3,3);

NumericMatrix xx(wrap(M));
NumericMatrix xx1(wrap(M));
NumericMatrix xx2(wrap(M));

base["xx"] = xx;
base["xx1"] = xx1;
base["xx2"] = xx2;

vector<string> lst;
lst.push_back("xx");
lst.push_back("xx1");
lst.push_back("xx2");
CharacterVector all = wrap(lst);

save(Named("list", all), Named("envir", base) , Named("file","Identities.RData"));
saveRDS(xx,Named("file","Identity.RDs"));
return wrap(M);

library(inline)
library(Rcpp)
library(RcppEigen)

src <- '
#put here cpp code shown above 
'

saveworkspace <- cxxfunction(signature(), src, plugin = "RcppEigen")
saveworkspace()
list.files(pattern="*.RD*")


[1] "Identity.RDs"
[2] "Identities.RData"

我不确定这个C++代码是否能在独立的库/可执行文件中工作。

NB:最初我错过了解决方案应该独立于R的评论,但对于那些正在寻找完全相同问题的人,但他们可以接受依赖于R,这可能会有所帮助。


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