我正在使用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;
}
Run Code Online (Sandbox Code Playgroud)
我很确定可以将标头中的条目打包回到StringVector中,但这似乎是一种蛮力的方法。我的问题是是否存在更优雅的解决方案。我不清楚这种结构在R:命名列表中将具有什么样的形式?
谢谢!
当我“源”文件时,这个最小的例子编译:
/*
read_header.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <RcppCommon.h>
typedef struct {
int my_data;
} MY_HEADER_INFO;
namespace Rcpp {
template <> SEXP wrap(const MY_HEADER_INFO& x);
}
#include <Rcpp.h>
namespace Rcpp {
template <>
SEXP wrap(const MY_HEADER_INFO& x) {
std::vector<std::string> names;
std::vector<SEXP> elements(1);
// do something with the elements and names
names.push_back("my_data");
elements[0] = Rcpp::wrap( x.my_data );
};
}
//' @export
// [[Rcpp::export]]
MY_HEADER_INFO read_header() {
MY_HEADER_INFO *header;
header = (MY_HEADER_INFO*)malloc(sizeof(MY_HEADER_INFO));
memset(header, 0, sizeof(MY_HEADER_INFO));
return *header;
}
Run Code Online (Sandbox Code Playgroud)
当我尝试在 RStudio 中将它构建到一个包 …
这看起来很简单,所以我希望我做错了什么。我升级了 R 和软件包,但现在我通过运行软件包 PDF 中的示例得到以下信息:
> sessionInfo()
R version 4.1.2 (2021-11-01)
Platform: x86_64-apple-darwin17.0 (64-bit)
Running under: macOS Big Sur 11.6
Matrix products: default
LAPACK: /Library/Frameworks/R.framework/Versions/4.1/Resources/lib/libRlapack.dylib
locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] iterators_1.0.13
loaded via a namespace (and not attached):
[1] compiler_4.1.2 parallel_4.1.2 tools_4.1.2 itertools_0.1-3 rJava_1.0-5
> library(iterators)
> i1 <- iter(1:3)
> nextElem(i1)
Error: StopIteration
>
Run Code Online (Sandbox Code Playgroud)
我没有看到任何其他帖子指出最新版本中的某些内容已损坏,所以我不知道从这里该去哪里。感谢您提供任何帮助、链接或信息!
给定一个命名列表:
values <- list( a=1, b=2 )
Run Code Online (Sandbox Code Playgroud)
我想生成一个逗号分隔的字符串,其中包含以下名称:
"a=1,b=2"
Run Code Online (Sandbox Code Playgroud)
以下作品,但看起来非常笨重:
library( iterators )
library( itertools )
fieldnames <- names(values)
sublist <- list()
iter_fieldnames <- ihasNext( iter( fieldnames ) )
iter_values <- ihasNext( iter( values ) )
while( hasNext( iter_fieldnames ) & hasNext( iter_values ) ) {
sublist <- append( sublist, paste0( nextElem( iter_fieldnames ), "=", nextElem( iter_values ) ) )
}
paste0( sublist, collapse="," )
[1] "a=1,b=2"
Run Code Online (Sandbox Code Playgroud)
在"粘贴""崩溃"的选择似乎那么优雅靠拢,但我无法弄清楚它是否可以进行分层(即,"首先,崩溃的名称和值用'=’,然后崩溃'’) :
paste0( paste0(names(values), values, collapse='='), collapse="," )
[1] "a1=b2"
Run Code Online (Sandbox Code Playgroud)
要么
paste0( paste0( …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 Rcpp 在 R 中运行 C 代码,但不确定如何转换用于保存文件数据的缓冲区。在下面的第三行代码中,我分配了一个 unsigned char 缓冲区,我的问题是我不知道要使用什么 Rcpp 数据类型。将数据读入缓冲区后,我想出了如何使用 Rcpp::NumericMatrix 来保存最终结果,而不是字符缓冲区。我已经看到 Dirk Eddelbuettel 对类似问题的几个回答,他建议用 Rcpp 初始化命令替换所有“malloc”调用。我尝试使用 Rcpp::CharacterVector,但最后在循环中存在类型不匹配:Rcpp::CharacterVector 无法读取为 unsigned long long int。该代码为某些 C 编译器运行,但为其他编译器抛出“内存损坏”错误,
FILE *fp = fopen( filename, "r" );
fseek( fp, index_data_offset, SEEK_SET );
unsigned char* buf = (unsigned char *)malloc( 3 * number_of_index_entries * sizeof(unsigned long long int) );
fread( buf, sizeof("unsigned long long int"), (long)(3 * number_of_index_entries), fp );
fclose( fp );
// Convert "buf" into a 3-column matrix.
unsigned long long int …Run Code Online (Sandbox Code Playgroud)