gpt4 book ai didi

使用 Rcpp 重写 R 的 cummin() 函数并允许使用 NA

转载 作者:行者123 更新时间:2023-12-01 14:21:20 27 4
gpt4 key购买 nike

我在学习 Rcpp .在这个例子中,我试图推出自己的 cummin()函数类似于基 R 的 cummin() ,除了我希望我的版本有 na.rm争论。这是我的尝试

小茴香

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
NumericVector cummin_cpp(NumericVector x, bool narm = false){
// Given a numeric vector x, returns a vector of the
// same length representing the cumulative minimum value
// if narm = true, NAs will be ignored (The result may
// contain NAs if the first values of x are NA.)
// if narm = false, the resulting vector will return the
// cumulative min until the 1st NA value is encountered
// at which point all subsequent entries will be NA

if(narm){
// Ignore NAs
for(int i = 1; i < x.size(); i++){
if(NumericVector::is_na(x[i]) | (x[i-1] < x[i])) x[i] = x[i-1];
}
} else{
// Don't ignore NAs
for(int i = 1; i < x.size(); i++){
if(NumericVector::is_na(x[i-1]) | NumericVector::is_na(x[i])){
x[i] = NA_REAL;
} else if(x[i-1] < x[i]){
x[i] = x[i-1];
}
}
}

return x;
}

foo.R

library(Rcpp)
sourceCpp("cummin.cpp")

x <- c(3L, 1L, 2L)
cummin(x) # 3 1 1
cummin_cpp(x) # 3 1 1

class(cummin(x)) # integer
class(cummin_cpp(x)) # numeric

我有几个问题..
  • R 的标准变量名是 na.rm ,不是 narm正如我所做的那样。但是,似乎我不能在 c++ 变量名中使用点。有没有办法解决这个问题,这样我就可以与 R 的约定保持一致?
  • 我不知道用户的输入是数字向量还是整数向量,所以我使用了 Rcpp 的 NumericVector 类型。不幸的是,如果输入是整数,则输出将转换为数字,这与基数 R 的 cummin() 不同。行为。人们通常如何处理这个问题?
  • 线路if(NumericVector::is_na(x[i]) | (x[i-1] < x[i])) x[i] = x[i-1];看起来很傻,但我不知道更好的方法来做到这一点。这里的建议?
  • 最佳答案

    我会用这个:

    template<typename T, int RTYPE>
    Vector<RTYPE> cummin_cpp2(Vector<RTYPE> x, bool narm){

    Vector<RTYPE> res = clone(x);
    int i = 1, n = res.size();
    T na;

    if(narm){
    // Ignore NAs
    for(; i < n; i++){
    if(ISNAN(res[i]) || (res[i-1] < res[i])) res[i] = res[i-1];
    }
    } else{
    // Do not ignore NAs
    for(; i < n; i++){
    if(ISNAN(res[i-1])) {
    na = res[i-1];
    break;
    } else if(res[i-1] < res[i]){
    res[i] = res[i-1];
    }
    }
    for(; i < n; i++){
    res[i] = na;
    }
    }

    return res;
    }


    // [[Rcpp::export]]
    SEXP cummin_cpp2(SEXP x, bool narm = false) {
    switch (TYPEOF(x)) {
    case INTSXP: return cummin_cpp2<int, INTSXP>(x, narm);
    case REALSXP: return cummin_cpp2<double, REALSXP>(x, narm);
    default: Rcpp::stop("SEXP Type Not Supported.");
    }
    }

    试试这个:
    x <- c(NA, 7, 5, 4, NA, 2, 4)
    x2 <- as.integer(x)

    cummin_cpp(x, narm = TRUE)
    x

    cummin_cpp(x2)
    x2


    x <- c(NA, 7, 5, 4, NA, 2, 4)
    x2 <- as.integer(x)
    x3 <- replace(x, is.na(x), NaN)

    cummin_cpp2(x, narm = TRUE)
    x

    cummin_cpp2(x2)
    x2

    cummin_cpp2(x3)
    x3

    解释:
  • Joran 的建议很好,只需将其包装在 R 函数中即可
  • 我按照 Joseph Wood 的建议使用调度员
  • 当心x通过引用传递,如果与您声明的类型相同,则会被修改(请参阅 these 2 slides )
  • 您需要办理NA以及 NaN
  • 您可以使用 ||而不是 |如果第一个条件为真,则仅评估第一个条件。
  • 关于使用 Rcpp 重写 R 的 cummin() 函数并允许使用 NA,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52012390/

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