将R函数转换为Rcpp
运行上述功能:将R函数转换为Rcpp,r,rcpp,R,Rcpp,运行上述功能: func.pheno <- function(tmp,p,tb,to,tc,g.gdd,v.gdd,r.gdd,ri.gdd){ tm <- tmp[1:length(tmp) >= p] fT <- ifelse(tm >= tb & tm <= to,(tm - tb)/(to - tb), ifelse(to <= tm & tm <= tc,(tc - tm)/(t
func.pheno <- function(tmp,p,tb,to,tc,g.gdd,v.gdd,r.gdd,ri.gdd){
tm <- tmp[1:length(tmp) >= p]
fT <- ifelse(tm >= tb & tm <= to,(tm - tb)/(to - tb),
ifelse(to <= tm & tm <= tc,(tc - tm)/(tc - to),0))
Te <- tb + fT*(to - tb)
thermal.units <- Te - tb
day.stage1 <- which.max(cumsum(thermal.units) >= g.gdd)
day.stage2 <- which.max(cumsum(thermal.units) >= v.gdd)
day.stage3 <- which.max(cumsum(thermal.units) >= r.gdd)
day.stage4 <- which.max(cumsum(thermal.units) >= ri.gdd)
day.stage4 <- ifelse(day.stage4 <= day.stage3, length(thermal.units),day.stage4)
list(day.stage1,day.stage2,day.stage3,day.stage4)
}
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
List PhenoModel(NumericVector day,
NumericVector temp,
NumericVector plant_date, # I noticed . is not accepted
double tb,
double to,
double tc,
double g_gdd,
double v_gdd,
double r_gdd,
double ri_gdd) {
int n = day.length();
NumericVector fT(n);
NumericVector Te(n);
NumericVector thermal_units(n);
for (int i = 1; i < n; i++){
# this tries to achieve this tm <- tmp[1:length(tmp) >= p]
for (int i = 0; i < n; i++){
if (day[i] < plant_date) {
temp[i] = 0;
} else {
temp[i] = temp[i];
}
if (temp[i] <= tb & temp[i] <= to) {
fT[i] = (temp[i] - tb)/(to - tb);
Te[i] <- tb + fT[i]*(to - tb);
thermal_units[i] <- Te[i] - tb;
} else if (to <= temp[i] & temp[i] <= tc) {
ft[i] = (tc - temp[i])/(tc - to);
Te[i] <- tb + fT[i]*(to - tb);
thermal_units[i] <- Te[i] - tb;
} else {
ft[i] = 0;
Te[i] <- tb + fT[i]*(to - tb);
thermal_units[i] <- Te[i] - tb;
}
我正在尝试开发一个Rcpp解决方案,因为我发现它对于其他功能更快。
我不是来自C++的背景,所以这就是我所做的。
df %>% group_by(year) %>% my function
#包括
使用名称空间Rcpp;
//[[Rcpp::导出]]
列表模式(数字媒介日,
数值向量温度,
我注意到,数字病媒植物日期不被接受
双肺结核,
加倍,
双tc,
双g_gdd,
双v_gdd,
双r_gdd,
双里夫(gdd){
int n=日长度();
数值向量fT(n);
数值向量Te(n);
数值矢量热单位(n);
对于(int i=1;i 如果(temp[i]如果要获取验证cumsum(x)>=thr的第一个索引,可以使用此Rcpp函数:
func.pheno <- function(tmp,p,tb,to,tc,g.gdd,v.gdd,r.gdd,ri.gdd){
tm <- tmp[1:length(tmp) >= p]
fT <- ifelse(tm >= tb & tm <= to,(tm - tb)/(to - tb),
ifelse(to <= tm & tm <= tc,(tc - tm)/(tc - to),0))
Te <- tb + fT*(to - tb)
thermal.units <- Te - tb
day.stage1 <- which.max(cumsum(thermal.units) >= g.gdd)
day.stage2 <- which.max(cumsum(thermal.units) >= v.gdd)
day.stage3 <- which.max(cumsum(thermal.units) >= r.gdd)
day.stage4 <- which.max(cumsum(thermal.units) >= ri.gdd)
day.stage4 <- ifelse(day.stage4 <= day.stage3, length(thermal.units),day.stage4)
list(day.stage1,day.stage2,day.stage3,day.stage4)
}
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
List PhenoModel(NumericVector day,
NumericVector temp,
NumericVector plant_date, # I noticed . is not accepted
double tb,
double to,
double tc,
double g_gdd,
double v_gdd,
double r_gdd,
double ri_gdd) {
int n = day.length();
NumericVector fT(n);
NumericVector Te(n);
NumericVector thermal_units(n);
for (int i = 1; i < n; i++){
# this tries to achieve this tm <- tmp[1:length(tmp) >= p]
for (int i = 0; i < n; i++){
if (day[i] < plant_date) {
temp[i] = 0;
} else {
temp[i] = temp[i];
}
if (temp[i] <= tb & temp[i] <= to) {
fT[i] = (temp[i] - tb)/(to - tb);
Te[i] <- tb + fT[i]*(to - tb);
thermal_units[i] <- Te[i] - tb;
} else if (to <= temp[i] & temp[i] <= tc) {
ft[i] = (tc - temp[i])/(tc - to);
Te[i] <- tb + fT[i]*(to - tb);
thermal_units[i] <- Te[i] - tb;
} else {
ft[i] = 0;
Te[i] <- tb + fT[i]*(to - tb);
thermal_units[i] <- Te[i] - tb;
}
#包括
使用名称空间Rcpp;
//[[Rcpp::导出]]
积分向量最小值(常数数值向量&x,双thr){
双和=0;
对于(int i=0;i=thr)返回IntegerVector::create(i+1);
}
返回IntegerVector::create();
}
这是一个相当冗长的问题(不是一个简单的例子)。你是在问“我该怎么做哪个.max(cumsum(x)>=y)”在C++中,你的R函数似乎只具有快速的向量化函数,所以RCPP的加速可能不像你希望的那么多。我同意@ DWW。我将指出一个问题:C++索引从0开始,而不是1。因此,<代码> > < /Calp>循环应该是:<代码>(int i=0;i < n;i++)< />代码。(例如,inti=1
->inti=0
)。从技术上讲,这就是我要寻找的which.max(cumsum(x)>=y)
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
IntegerVector min_ind_which(const NumericVector& x, double thr) {
double sum = 0;
for (int i = 0; i < x.size(); i++) {
sum += x[i];
if (sum >= thr) return IntegerVector::create(i + 1);
}
return IntegerVector::create();
}