Rcpp 中的 lengths() 糖函数?
A lengths() sugar function in Rcpp?
在 base 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() 函数,但我想在这一步优化我的速度。谢谢!
我不知道等效的糖函数,所以很想知道是否也存在。而且我知道你说你可以自己写,但我会用我使用的这两个功能把我的帽子扔进戒指。一种是递归的,所以它决定了每个子列表元素的大小,另一种相当于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
在 base 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() 函数,但我想在这一步优化我的速度。谢谢!
我不知道等效的糖函数,所以很想知道是否也存在。而且我知道你说你可以自己写,但我会用我使用的这两个功能把我的帽子扔进戒指。一种是递归的,所以它决定了每个子列表元素的大小,另一种相当于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