繁体   English   中英

尝试使用 Boost 对 Rcpp 进行 T 测试:“未命名成员”错误

[英]Attempting to do a T test with Rcpp using Boost: "No member named" errors

我正在尝试通过使用 Rcpp 更快地在 R 中进行一些统计计算。 首先,我用 R 编写代码。然后我使用 Qt Creator 用 C++ 编写代码,这需要我使用 Boost 包。 现在,当我尝试使用sourceCpp()编译一个使用boost::math::statistics::two_sample_t_test()的简单函数时,我收到两个错误——单击此处查看它在 RStudio 中的外观。

/Library/Frameworks/R.framework/Versions/3.6/Resources/library/BH/include/boost/compute/algorithm/random_shuffle.hpp
命名空间“std”中没有名为“random_shuffle”的成员; 你的意思是简单的'random_shuffle'吗?

~/Documents/Research/P 值校正项目/Perm FDR with C++ using Rcpp/PermFDR_R/Rcpp.cpp
命名空间“boost::math::statistics”中没有名为“two_sample_t_test”的成员

这是发生这种情况时弹出的 /Library/Frameworks/R.framework/Versions/3.6/Resources/library/BH/include/boost/compute/algorithm/random_shuffle.hpp 中代码的屏幕截图。

这是R代码。

library(Rcpp)
library(rstudioapi)
library(BH)

Sys.setenv("PKG_CXXFLAGS"="-std=c++17")
sourceCpp("Rcpp.cpp")

这是 C++ 代码。

//[[Rcpp::depends(BH)]]
#include <Rcpp.h>
#include <vector>
#include <cmath>
#include <iostream>
#include <random>
#include <boost/math/statistics/t_test.hpp>
#include <boost/math/distributions/students_t.hpp>
#include <boost/math/tools/univariate_statistics.hpp>
#include <boost/compute/algorithm/random_shuffle.hpp>
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/mean.hpp>
#include <iomanip>
#include <numeric>
#include <random>

//[[Rcpp::plugins(cpp17)]]

using namespace std;
#include <Rcpp.h>
using namespace Rcpp;

/*
 * Performs a T test on the measurements according to the design (1s and 2s)
 * and returns a P value.
 */
double designTTest(vector<double> ints, vector<int> design) {
  if (ints.size() != design.size()) {
    cout << "ERROR: DESIGN VECTOR AND MEASUREMENT VECTOR NOT EQUAL IN LENGTH!";
    throw;
  }
  
  vector<double> cIntensities;
  vector<double> tIntensities;
  
  for (int i = 0; i < design.size(); i++) {
    if (design[i] == 1) {
      cIntensities.push_back(ints[i]);
    } else if (design[i] == 2) {
      tIntensities.push_back(ints[i]);
    } else {
      cout << "ERROR: DESIGN SYMBOL IS NOT 1 OR 2!";
      throw;
    }
  }
  
  auto [t, p] = boost::math::statistics::two_sample_t_test(cIntensities, tIntensities);
  return p;
}

// [[Rcpp::export]]
double ttestC(NumericVector ints, NumericVector design) {
  vector<double> intVec = as<std::vector<double>>(ints);
  vector<int> designVec = as<std::vector<int>>(design);
  return designTTest(intVec, designVec);
}

谢谢!!

您的问题有很多内容,我不确定我是否理解所有内容(“设计排序”非常不清楚)。

但是,我可以帮助您了解Rcpp的机制以及通过BH使用Boost 我可以提出一些改变:

  • 您不需要指定 C++11 或 C++17; R 在最新版本下已经默认为 C++14(如果编译器支持)(编辑:我们重新添加 C++17 以确保结构化绑定工作)
  • 你不需要所有这些标题:我们需要一个用于Rcpp一个用于Boost
  • 我建议不要using namespace ...并建议明确命名
  • 您不需要从 R 向量到std::vector<...>的包装器,因为Rcpp为您执行此操作
  • 我通过Rcpp::stop()简化了错误报告

有了这一切,再加上一个运行该函数的迷你演示,您的代码变得更简单、更短。

代码

// [[Rcpp::depends(BH)]]
// [[Rcpp::plugins(cpp17)]]

#include <Rcpp.h>
#include <boost/math/statistics/t_test.hpp>

// Performs a T test on the measurements according to the design (1s and 2s)
// and returns a P value.
// [[Rcpp::export]]
double designTTest(std::vector<double> ints, std::vector<double> design) {
    if (ints.size() != design.size()) Rcpp::stop("ERROR: DESIGN VECTOR AND MEASUREMENT VECTOR NOT EQUAL IN LENGTH!");
    std::vector<double> cIntensities, tIntensities;
    for (size_t i = 0; i < design.size(); i++) {
        if (design[i] == 1) {
            cIntensities.push_back(ints[i]);
        } else if (design[i] == 2) {
            tIntensities.push_back(ints[i]);
        } else {
            Rcpp::stop("ERROR: DESIGN SYMBOL IS NOT 1 OR 2!");
        }
    }

    auto [t, p] = boost::math::statistics::two_sample_t_test(cIntensities, tIntensities);
    return p;
}

/*** R
designTTest(c(1,2,1,2,1), c(2,1,2,1,2))
*/

我们可以将其用于编译示例(可能包含无意义的数据)。

输出

> Rcpp::sourceCpp("~/git/stackoverflow/72652032/answer.cpp")

> designTTest(c(1,2,1,2,1), c(2,1,2,1,2))
[1] 0
> 

当您在~/.R/Makevars中将-Wno-parentheses添加到CXXFLAGS时,我删除了一堆编译噪音。 CRAN 不允许我(作为BH维护者)保持上游#pragmas如此嘈杂,它是......

在完整的编译器输出中,boost 告诉您不应该包含<boost/math/tools/univariate_statistics.hpp> 您应该包含<boost/math/statistics/univariate_statistics.hpp>代替:

/usr/include/boost/math/tools/univariate_statistics.hpp:15:1: note: ‘#pragma message: This header is deprecated. Use <boost/math/statistics/univariate_statistics.hpp> instead.’

遵循该建议,我不再收到std::random_shuffle错误消息。


关于two_sample_t_test的另一个错误消息可能是因为它是最近才添加到 boost 的,版本为 1.76,请参阅https://github.com/boostorg/math/pull/487 您可能使用的是旧版本。

暂无
暂无

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

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