将R转换为Rcpp:向量中连续日期之间的平均时间差

时间:2016-10-04 00:27:40

标签: c++ r rcpp

我有一个R函数,它接受一个排序日期(降序)的向量,它返回向量中连续日期之间的平均时间差。我试图将此R函数转换为Rcpp函数。

这是我到目前为止所做的:

minute.step

这是我目前打破Rcpp的翻译:

sorted_dates <- as.Date(c("2015-09-25", "2015-06-12",
                        "2015-06-12", "2015-03-26"))

mean_time_difference <- function(sorted_dates){
### Takes a vector of dates sorted in descending order
### Returns the mean time difference between dates.

time_differences <- integer()
for(i in 1:(length(sorted_dates) - 1)){
time_differences[i] <- as.integer( sorted_dates[i] - sorted_dates[i+1])
}

return(mean(time_differences))

}

我确信在R和Rcpp函数中都有很多可以改进的东西。谁能告诉我如何在Rcpp中最好地实现该功能?

4 个答案:

答案 0 :(得分:3)

这是您正在寻找的,采用简单的R方法:

> sorted_dates <- as.Date(c("2015-09-25", "2015-06-12", 
+                         "2015-06-12", "2015-03-26"))
> mean(diff(sorted_dates))
Time difference of -61 days
> mean(as.numeric(diff(sorted_dates)))
[1] -61
> 

可以使用Rcpp执行这些操作,但您可能在基本R或任何附加聚合实用程序中执行这些操作 - 我喜欢data.table。

答案 1 :(得分:2)

编辑:我刚注意到@Frank已在评论中提出这一点。我仍然认为代码很有用,所以我会把它留在这里。

只是为了补充一点,你的问题实际上比它看起来更简单,并且因为你(我假设)正在寻找一个快速处理的解决方案,它可以更好地帮助你简化问题,而不是尝试重新编码它用不同的语言。特别是因为您不需要进行任何排序,只需将日期设置为原样,然后应用以下内容。

您要求排序后的一组数字之间的平均差异,这与:

相同
as.numeric( ( max( dates ) - min( dates ) ) / ( length( dates ) - 1L ) )

这是系列的总范围,除以“间隙”的数量(等于值的数量减去1)。

我还没有测试过,但我相信上面会比其他方法快得多,特别是对于大型数据集。

答案 2 :(得分:1)

很少注意到:

  1. C ++索引从0开始而不是1!
  2. 使用[] not 提供边界检查(导致未定义的行为),其中() 提供访问数组的边界检查。
  3. 避免使用.push_back,因为它会复制数据,因为代理模型会导致很多心痛(更多的是减速)。
  4. 此外,您可能应该将此功能拆分为时间差异例程(see a differencing generic for armadillo),然后是平均功能。
  5. 现在,一些代码的时间:

    // [[Rcpp::export]]
    Rcpp::IntegerVector diff_date(Rcpp::DateVector sorted_dates){
      // Length of Time Series
      unsigned int n = sorted_dates.size();
    
      // Initialize result   
      Rcpp::IntegerVector time_diff(n-1);
    
      // Difference operator X_t - X_{t+1}
      for(unsigned int i = 0; i < (n-1); i++){
        time_diff[i] = sorted_dates[i] - sorted_dates[i+1];
      }
    
      // Return differenced series:
      return time_diff;
    }
    
    // [[Rcpp::export]]
    double mean_diff_date(Rcpp::DateVector sorted_dates){
    
      // Difference time series by above routine
      Rcpp::IntegerVector time_diff = diff_date(sorted_dates);
    
      // Length of Time Series
      unsigned int n = time_diff.size();
    
      // Mean routine (could be replaced with mean() )
      double total = 0;
    
      for(unsigned int i = 0; i < n; i++){
         total += time_diff[i];
      }
    
      return total/n;
    }
    

答案 3 :(得分:-2)

为了完整性,请遵循@DirkEddelbuettel的提示,这是使用Rcpp的解决方案:

cppFunction('double mean_time_diff(DateVector sorted_dates) {

  int n = sorted_dates.size();
  IntegerVector time_diff;

  for(int i=0; i < (n-1); i++){
    time_diff.push_back( sorted_dates[i] - sorted_dates[i+1] );
  }

  int m = time_diff.size();
  double total = 0; 

  for(int i=0; i < m; i++) {
    total += time_diff[i];
  }

  return total / m;

}')

关键是要记住C ++是零索引的。