Tôi bắt đầu phát xung quanh với Rcpp
và muốn sử dụng chức năng fastLm
làm ví dụ (cũng vì nó hữu ích cho công việc sau này). Tôi biết rằng fastLm
là một phần của gói RcppArmadillo
nhưng tôi muốn biên dịch nó bằng cách sử dụng sourceCpp
. Mã này có thể được tìm thấy here và cũng ở dưới đây. Vấn đề đầu tiên tôi gặp phải là tôi không thể chỉ cần chạy sourceCpp("fastLm.cpp")
trong R sau khi cài đặt và tải Rcpp
và RcppArmadillo
. Tôi nhận được lỗi này error: RcppArmadillo.h: No such file or directory
và sau đó là tất cả mọi thứ mà tôi đoán theo đó.Sử dụng `sourceCpp` để biên dịch` fastLm`
Vấn đề thứ hai là tôi nghĩ rằng tôi cần phải thay đổi một số nội dung trong số fastLm.cpp
. Những thay đổi của tôi cũng dưới đây nhưng tôi chắc chắn có điều gì đó bị thiếu hoặc sai. Tôi đã bao gồm #include <Rcpp.h>
và using namespace Rcpp;
và // [[Rcpp::export]]
để xuất hàm sang R và tôi đã thay đổi đối số từ SEXP
thành NumericVector
và NumericMatrix
. Tôi không thấy lý do tại sao mà không nên làm việc và điều chỉnh tương tự có lẽ là có thể cho giá trị trả lại?
fastLm.cpp
#include <RcppArmadillo.h>
extern "C" SEXP fastLm(SEXP ys, SEXP Xs) {
Rcpp::NumericVector yr(ys); // creates Rcpp vector from SEXP
Rcpp::NumericMatrix Xr(Xs); // creates Rcpp matrix from SEXP
int n = Xr.nrow(), k = Xr.ncol();
arma::mat X(Xr.begin(), n, k, false); // reuses memory and avoids extra copy
arma::colvec y(yr.begin(), yr.size(), false);
arma::colvec coef = arma::solve(X, y); // fit model y ~ X
arma::colvec resid = y - X*coef; // residuals
double sig2 = arma::as_scalar(arma::trans(resid)*resid/(n-k));
// std.error of estimate
arma::colvec stderrest = arma::sqrt(sig2 * arma::diagvec(arma::inv(arma::trans(X)*X)));
return Rcpp::List::create(
Rcpp::Named("coefficients") = coef,
Rcpp::Named("stderr") = stderrest
) ;
}
fastLm.cpp thay đổi
#include <Rcpp.h>
#include <RcppArmadillo.h>
using namespace Rcpp;
// [[Rcpp::export]]
extern "C" SEXP fastLm(NumericVector yr, NumericMatrix Xr) {
int n = Xr.nrow(), k = Xr.ncol();
arma::mat X(Xr.begin(), n, k, false); // reuses memory and avoids extra copy
arma::colvec y(yr.begin(), yr.size(), false);
arma::colvec coef = arma::solve(X, y); // fit model y ~ X
arma::colvec resid = y - X*coef; // residuals
double sig2 = arma::as_scalar(arma::trans(resid)*resid/(n-k));
// std.error of estimate
arma::colvec stderrest = arma::sqrt(sig2 * arma::diagvec(arma::inv(arma::trans(X)*X)));
return Rcpp::List::create(
Rcpp::Named("coefficients") = coef,
Rcpp::Named("stderr") = stderrest
) ;
}
Tốt. Điều duy nhất là mất tích bây giờ là khối try/catch mà ví dụ của OP cũng bỏ qua (nhưng đó là trong src). –