gpt4 book ai didi

rcpp - 在 Rcpp 中,如何从 C 到 R 中获取用户定义的结构

转载 作者:行者123 更新时间:2023-12-03 15:49:42 24 4
gpt4 key购买 nike

我正在使用 Rcpp 包并且可以让我的 C 函数在 R 中编译和运行,但现在我想将一个大型的、用户定义的数据结构返回给 R。结构中的字段是数字或字符串 - 没有新的或奇怪的类型结构内。下面的例子是简化的,不能编译,但它传达了我的问题的想法。

    typedef struct {
char* firstname[128];
char* lastname[128];
int nbrOfSamples;
} HEADER_INFO;

// [[Rcpp::export]]
HEADER_INFO* read_header(Rcpp::StringVector strings) {
FILE *fp;
MEF_HEADER_INFO *header;

char * filename = (char*)(strings(0));
char * password = (char*)(strings(1));

header = (HEADER_INFO*)malloc(sizeof(HEADER_INFO));
memset(header, 0, sizeof(HEADER_INFO));

fp = fopen(filename, "r");
(void)read_header(header, password);
return header;
}

我很确定我可以将 header 中的条目打包回 StringVector,但这似乎是一种蛮力方法。我的问题是是否存在更优雅的解决方案。我不清楚这样的结构在 R 中有什么形式:命名列表?

谢谢!

最佳答案

R 中的正确结构取决于您的 struct看起来完全一样。命名列表是最通用的列表。这里是 wrap 的简单示例实现评论中提到的功能:

#include <RcppCommon.h>

typedef struct {
char* firstname[128];
char* lastname[128];
int nbrOfSamples;
} HEADER_INFO;

namespace Rcpp {
template <>
SEXP wrap(const HEADER_INFO& x);
}

#include <Rcpp.h>

namespace Rcpp {
template <>
SEXP wrap(const HEADER_INFO& x) {
Rcpp::CharacterVector firstname(x.firstname, x.firstname + x.nbrOfSamples);
Rcpp::CharacterVector lastname(x.lastname, x.lastname + x.nbrOfSamples);
return Rcpp::wrap(Rcpp::List::create(Rcpp::Named("firstname") = firstname,
Rcpp::Named("lastname") = lastname,
Rcpp::Named("nbrOfSamples") = Rcpp::wrap(x.nbrOfSamples)));
};
}

// [[Rcpp::export]]
HEADER_INFO getHeaderInfo() {
HEADER_INFO header;
header.firstname[0] = (char*)"Albert";
header.lastname[0] = (char*)"Einstein";
header.firstname[1] = (char*)"Niels";
header.lastname[1] = (char*)"Bohr";
header.firstname[2] = (char*)"Werner";
header.lastname[2] = (char*)"Heisenberg";
header.nbrOfSamples = 3;
return header;
}

/*** R
getHeaderInfo()
*/

输出:

> getHeaderInfo()
$firstname
[1] "Albert" "Niels" "Werner"

$lastname
[1] "Einstein" "Bohr" "Heisenberg"

$nbrOfSamples
[1] 3

但是,对于这种特殊情况, data.frame使用起来会更自然,可以通过替换上面的 wrap来实现和:

  template <>
SEXP wrap(const HEADER_INFO& x) {
Rcpp::CharacterVector firstname(x.firstname, x.firstname + x.nbrOfSamples);
Rcpp::CharacterVector lastname(x.lastname, x.lastname + x.nbrOfSamples);
return Rcpp::wrap(Rcpp::DataFrame::create(Rcpp::Named("firstname") = firstname,
Rcpp::Named("lastname") = lastname));
};

输出:

> getHeaderInfo()
firstname lastname
1 Albert Einstein
2 Niels Bohr
3 Werner Heisenberg

关于rcpp - 在 Rcpp 中,如何从 C 到 R 中获取用户定义的结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51110244/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com