gpt4 book ai didi

r - 在 Rcpp 中通过调用 `[data.frame` 对 data.frame 进行子集化时避免 SIGSEGV

转载 作者:行者123 更新时间:2023-12-02 01:23:40 24 4
gpt4 key购买 nike

由于我不明白的原因,我的 Rcpp 代码偶尔会失败(SEGFAULT 等)。该代码创建了一个大型 data.frame,然后尝试通过调用 R 子集函数 [.data.frame) 从正在创建的同一方法中获取此 data.frame 的子集框架。它的一个非常简化的版本如下所示:

library(Rcpp)
src <- '// R function to subset data.frame - what will be called to subset
DataFrame test() {
Function subsetinR("[.data.frame");

// Make a dataframe in Rcpp to subset
size_t n = 100;
auto df = DataFrame::create(Named("a") = std::vector<double> (n, 2.0),
Named("b") = std::vector<double> (n, 4.0));

// Now make a vector to subset with
LogicalVector filter = LogicalVector::create(n, TRUE);
for (size_t i =0; i < n; i++) {
if (i % 2 == 0) filter[i] = FALSE;
}

// Subset, here is where it fails!
df = subsetinR(df, filter, R_MissingArg);
return df;
}'

fun <- cppFunction(plugins=c("cpp11"), src, verbose = TRUE, depends="Rcpp")
fun()

然而,虽然这偶尔有效,但有时会失败并出现以下错误:

*** caught segfault ***
address 0x7ff700000030, cause 'memory not mapped'`

谁知道出了什么问题?

注意:这不是重复。我已经看到其他堆栈溢出答案,它们通过利用每个向量的子集来创建向量,例如

  // Next up, create a new DataFrame Object with selected rows subset. 
return Rcpp::DataFrame::create(Rcpp::Named("val1") = val1[idx],
Rcpp::Named("val2") = val2[idx],
Rcpp::Named("val3") = val3[idx],
Rcpp::Named("val3") = val4[idx]
);

但是,我明确希望避免重复的 [idx] 子集,因为在构造 data.frame 时不知道 idx(它只在最后才知道),而且我我希望找到一种不涉及重复调用它的方法。不过,如果最后可以一次性转换 data.frame,那就没问题了。

最佳答案

这里的问题是 LogicalVector::create() 没有按照您的预期进行操作——它返回一个长度为 2 的向量,包含元素 TRUE。换句话说,您的代码:

LogicalVector filter = LogicalVector::create(n, TRUE);

生成的不是长度为 n 且值为 TRUE 的逻辑向量,而是长度为 2 且第一个元素为“truthy”的逻辑向量,因此 TRUE,第二个显式 TRUE

您可能打算只使用常规构造函数,例如LogicalVector(n, TRUE)

关于r - 在 Rcpp 中通过调用 `[data.frame` 对 data.frame 进行子集化时避免 SIGSEGV,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38448213/

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