Rcpp 中的 lengths() 糖函数?

Posted

技术标签:

【中文标题】Rcpp 中的 lengths() 糖函数?【英文标题】:A lengths() sugar function in Rcpp? 【发布时间】:2019-12-17 16:56:29 【问题描述】:

在基数 R 中,lengths() 函数计算列表中每个元素的长度。例如,

> mylist = list(v1 = c(1,2,3), v2 = c(1,2), v3 = c(1,2,3,4))
> mylist
$`v1`
[1] 1 2 3

$v2
[1] 1 2

$v3
[1] 1 2 3 4

> lengths(mylist)
v1 v2 v3 
 3  2  4 

在 Rcpp(或来自 Armadillo)中是否有类似的功能?我知道可以编写一个基于 Rcpp 的 apply() 函数,但我想在这一步优化我的速度。谢谢!

【问题讨论】:

【参考方案1】:

我不知道等效的糖功能,所以很想知道是否也存在。我知道你说你可以自己写,但我会用我使用的这两个函数把我的帽子扔进戒指。一种是递归的,所以它决定了每个子列表元素的大小,另一种相当于lengths()(非递归)。

library(Rcpp)

cppFunction(

  code = 'Rcpp::List rcpp_lengths_recursive( const Rcpp::List& lst ) 
  std::size_t n = lst.size();
  Rcpp::List res( n ); 
  std::size_t i;

  for( i = 0; i < n; i++ ) 
    switch( TYPEOF( lst[i] ) ) 
      case VECSXP: 
        // might need an `Rf_inherits( lst[i], "data.frame" )` check, 
        // depending on your use-case
        res[ i ] = rcpp_lengths_recursive( lst[i] );
        break;
      
      default: 
        int n_elements = Rf_length( lst[i] );
        res[i] = n_elements;
      
    
  
  return res;
'

)

cppFunction(

  code = 'Rcpp::IntegerVector rcpp_lengths( const Rcpp::List& lst ) 
    std::size_t n = lst.size();
    Rcpp::IntegerVector res( n );
    std::size_t i;

    for( i = 0; i < n; i++ ) 
      res[i] = Rf_length( lst[i] );
    
    return res;
  '

)

mylist <- list(v1 = c(1,2,3), v2 = c(1,2), v3 = list(list(c(1,2,3,4)), 1:2))

rcpp_lengths( mylist )
# [1] 3 2 2

rcpp_lengths_recursive( mylist )
# [[1]]
# [1] 3
# 
# [[2]]
# [1] 2
# 
# [[3]]
# [[3]][[1]]
# [[3]][[1]][[1]]
# [1] 4
# 
# 
# [[3]][[2]]
# [1] 2

【讨论】:

以上是关于Rcpp 中的 lengths() 糖函数?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在 Rcpp 中使用“pnorm”时出现错误

如何从 Rcpp 中的另一个函数调用一个函数?

内存在简单的Rcpp函数中泄漏

Rcpp 程序中的最小值和最大值

使用 Rcpp 在 C++ 函数的 R 中使用 for 循环的内存问题

在构建 R 包时从另一个 Rcpp 函数调用 Rcpp 函数