简体   繁体   English

从 C++ 写一个 Rdata 文件

[英]write an Rdata file from C++

Suppose I have a C++ program that has a vector of objects that I want to write out to an Rdata data.frame file, one observation per element of the vector.假设我有一个 C++ 程序,它有一个对象向量,我想写出到 Rdata data.frame 文件,向量的每个元素一个观察。 How can I do that?我怎样才能做到这一点? Here is an example.这是一个例子。 Suppose I have假设我有

vector<Student> myStudents;

And Student is a class which has two data members, name which is of type std::string and grade which is of type int . Student是一个有两个数据成员的类, namestd::string类型, gradeint类型。

Is my only option to write a csv file?是我编写 csv 文件的唯一选择吗?

Note that Rdata is a binary format so I guess I would need to use a library.请注意,Rdata 是一种二进制格式,所以我想我需要使用一个库。

A search for Rdata [r] [C++] came up empty.对 Rdata [r] [C++] 的搜索结果为空。

I think nobody has bothered to extract a binary file writer from the R sources to be used independently from R.我认为没有人费心从 R 源中提取二进制文件编写器以独立于 R 使用。

Almost twenty years ago I did the same for Octave files as their format is simply: two integers for 'n' and 'k', followed by 'n * k' of data -- so you could read / write with two function calls each.大约二十年前,我对 Octave 文件做了同样的处理,因为它们的格式很简单:'n' 和 'k' 的两个整数,后跟数据的 'n * k' —— 这样你就可以读/写每个函数调用两个函数.

I fear that for R you would have to cover too many of R's headers -- so the easiest (?) route may be to give the data to R, maybe via Rserve ('loose' connection over tcp/ip) and RInside (tighter connection via embedding), and have R write it.我担心对于 R,您将不得不覆盖太多 R 的标头——所以最简单的(?)路由可能是将数据提供给 R,可能通过 Rserve(通过 tcp/ip 的“松散”连接)和 RInside(更紧密通过嵌入连接),并让 R 编写它。

Edit: In the years since the original answer was written, one such library has been created: librdata .编辑:在编写原始答案后的几年里,已经创建了一个这样的库: librdata

I don't know if this will fit everyone needs (of those who is googling this question), but this way you can save individual or multiple variables:我不知道这是否适合每个人的需求(那些在谷歌上搜索这个问题的人),但这样你可以保存单个或多个变量:

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"

I'm not 100% sure if this C++ code will work in standalone library/executable.我不是 100% 确定这个 C++ 代码是否可以在独立库/可执行文件中工作。

NB : Initially I missed the comment that the solution should be independent of R , but for those who is searching for exactly the same question, but they are ok with dependency on R , this could be helpful.注意:最初我错过了解决方案应该独立于R的评论,但是对于那些正在寻找完全相同的问题但他们可以依赖于R ,这可能会有所帮助。

Here is an example of a function that saves a list in a RData.这是将列表保存在 RData 中的函数示例。 This example is based on the previous answer :此示例基于先前的答案:

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";
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM