C++ 如何告诉C++;根据索引指示器放弃向量中的某些元素
我正在使用RCPP来加速我的项目中的R代码。现在我要做的是把我的R代码转换成使用ARMADILO包的C++。我发现我经常写C++中的多行来替换R.中的一行。p> 我的问题是: 我有一个向量存储数据:数据。我还有一个矩阵,存储了我需要访问的元素的索引。请允许我首先在R中说明我的场景:C++ 如何告诉C++;根据索引指示器放弃向量中的某些元素,c++,c,r,matrix,C++,C,R,Matrix,我正在使用RCPP来加速我的项目中的R代码。现在我要做的是把我的R代码转换成使用ARMADILO包的C++。我发现我经常写C++中的多行来替换R.中的一行。p> 我的问题是: 我有一个向量存储数据:数据。我还有一个矩阵,存储了我需要访问的元素的索引。请允许我首先在R中说明我的场景: > Data [1] 4 5 6 7 8 及 对于“索引”矩阵的每一行,我想从数据中获得相应的元素。在R中,我只需要这样编码: > Data[index[1,]] [1] 4 5 6 > Dat
> Data
[1] 4 5 6 7 8
及
对于“索引”矩阵的每一行,我想从数据中获得相应的元素。在R中,我只需要这样编码:
> Data[index[1,]]
[1] 4 5 6
> Data[index[2,]]
[1] 4
> Data[index[3,]]
[1] 5 5
i、 e。
我需要从“索引”矩阵的第一行得到的元素是数据[1],数据[2],数据[3]
我需要的第二行“索引”矩阵中的元素是
资料[1]
从“索引”矩阵的第三行中我需要的元素是
数据[2]数据[2]
R的便利之处在于,R自动将0索引标识为“nothing”,并且不会访问它
现在我把向量“数据”和矩阵“索引”输入到C中。我想知道是否有任何方法可以达到与上述R类似的结果?非常感谢 基本R 您可以使用索引将数据子集,结果将是一个列表
Data <- c( 4 ,5 ,6, 7, 8)
index <- matrix(c(1,2,3, 1, 0, 0, 2,0,2), byrow = TRUE, nrow = 3)
apply(index, 1, function(x) Data[x])
# [[1]]
# [1] 4 5 6
#
# [[2]]
# [1] 4
#
# [[3]]
# [1] 5 5
Rcpp:对于0索引,在
数据
向量中使用NA
您只需将apply
转换为Rcpp
代码,如前所述
或
使用[
:有关使用RCpp的向量子集的更多信息,请参阅此
文件:mysubset.cpp
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector mysubset(NumericVector Data, NumericVector index) {
return Data[index];
}
#包括
使用名称空间Rcpp;
//[[Rcpp::导出]]
NumericVector mysubset(NumericVector数据、NumericVector索引){
返回数据[索引];
}
RStudio:
library('Rcpp')
sourceCpp("mysubset.cpp")
Data <- c( NA, 4 ,5 ,6, 7, 8) # for 0 index, use NA
index <- matrix(c(1,2,3, 1, 0, 0, 2,0,2), byrow = TRUE, nrow = 3)
matrix( mysubset(Data, index), nrow = 3, byrow = FALSE)
# [,1] [,2] [,3]
# [1,] 4 5 6
# [2,] 4 NA NA
# [3,] 5 NA 5
mysubset(Data, index[1,])
# [1] 4 5 6
na.omit(mysubset(Data, index[2,]))
# [1] 4
library('Rcpp')
sourceCpp(“mysubset.cpp”)
C++中的数据,还有一点工作要做,但可行的是:
#include <type_traits>
#include <vector>
#include <iterator>
#include <algorithm>
#include <iostream>
#include <utility>
template <typename T, typename I,
typename std::enable_if<std::is_convertible<I,
typename std::vector<T>::size_type>::value>::type* = nullptr>
std::vector<std::vector<T>> product (const std::vector<T>& data,
const std::vector<std::vector<I>>& index) {
std::vector<std::vector<T>> result (index.size());
std::transform(std::begin(index),
std::end(index),
std::make_move_iterator(std::begin(result)),
[&data, &filler](const std::vector<I>& index_row) {
std::vector<T> row;
for (auto& pos : index_row) {
if (pos > 0) {
row.push_back(data.at(pos - 1));
}
}
return row;
});
return result;
}
演示中使用的辅助函数:
template <typename T>
std::ostream& operator << (std::ostream& oss, const std::vector<T>& v) {
for (auto &item : v) {
oss << item << ",";
}
return oss;
}
template <typename T>
std::ostream& operator << (std::ostream& oss, const std::vector<std::vector<T>>& vv) {
for (auto &v : vv) {
oss << v << "\n";
}
return oss;
}
模板
std::ostream&operator如果您想让事情变得简单,那么我建议您:
假设您有一个数据向量(data
):
然后,以下代码将获取一行索引
的索引。获取数据
的索引元素,并将其附加到结果向量,除非索引为0(或超出范围):
理论上,你需要一个算法,比如“代码> STD::TrimeIf如果。但是请参阅< /P> C或C++。或者两者都有。你的标题和介绍都是C++的,但是在最后一段中你提到C.sorry,我认为它是类似的……IMO我认为C++是C的扩展,它可以实现目标编程……只要Curr我不会处理目标编程,所以我认为这是同样的感谢你的代码!也许我有点远没有完全理解。但这绝对是我在RCPP使用和学习C++的一个很好的模板!明白了!我学到了很多关于R的事实!你给我的最后一个解决方案真是太棒了!这是最直接的。RD C++代码我能理解,谢谢!
library('Rcpp')
sourceCpp("mysubset.cpp")
Data <- c( NA, 4 ,5 ,6, 7, 8) # for 0 index, use NA
index <- matrix(c(1,2,3, 1, 0, 0, 2,0,2), byrow = TRUE, nrow = 3)
matrix( mysubset(Data, index), nrow = 3, byrow = FALSE)
# [,1] [,2] [,3]
# [1,] 4 5 6
# [2,] 4 NA NA
# [3,] 5 NA 5
mysubset(Data, index[1,])
# [1] 4 5 6
na.omit(mysubset(Data, index[2,]))
# [1] 4
#include <type_traits>
#include <vector>
#include <iterator>
#include <algorithm>
#include <iostream>
#include <utility>
template <typename T, typename I,
typename std::enable_if<std::is_convertible<I,
typename std::vector<T>::size_type>::value>::type* = nullptr>
std::vector<std::vector<T>> product (const std::vector<T>& data,
const std::vector<std::vector<I>>& index) {
std::vector<std::vector<T>> result (index.size());
std::transform(std::begin(index),
std::end(index),
std::make_move_iterator(std::begin(result)),
[&data, &filler](const std::vector<I>& index_row) {
std::vector<T> row;
for (auto& pos : index_row) {
if (pos > 0) {
row.push_back(data.at(pos - 1));
}
}
return row;
});
return result;
}
auto main() -> int {
std::vector<int> data = {4, 5, 6, 7, 8};
std::vector<std::vector<int>> index = {
{1, 2, 3},
{1, 0, 0},
{2, 0, 2}
};
std::vector<std::vector<int>> result = std::move(product(data, index));
std::cout << result << "\n";
}
4,5,6,
4,
5,5,
template <typename T>
std::ostream& operator << (std::ostream& oss, const std::vector<T>& v) {
for (auto &item : v) {
oss << item << ",";
}
return oss;
}
template <typename T>
std::ostream& operator << (std::ostream& oss, const std::vector<std::vector<T>>& vv) {
for (auto &v : vv) {
oss << v << "\n";
}
return oss;
}
std::vector<int> Data{ 4, 5, 6, 7, 8 };
std::vector<std::vector<int>> index{ {1, 2, 3}, {1, 0, 0}, {2, 0, 2} };
std::vector<int> r;
for (auto i : index[1-1])
if (i > 0 && i <= Data.size())
r.push_back(Data[i-1]);
#include <vector>
#include <iostream>
std::vector<int> Data{ 4, 5, 6, 7, 8 };
std::vector<std::vector<int>> index{ {1, 2, 3}, {1, 0, 0}, {2, 0, 2} };
std::vector<int> r1, r2, r3;
for (auto i : index[1-1]) if (i > 0 && i <= Data.size()) r1.push_back(Data[i-1]);
for (auto i : index[2-1]) if (i > 0 && i <= Data.size()) r2.push_back(Data[i-1]);
for (auto i : index[3-1]) if (i > 0 && i <= Data.size()) r3.push_back(Data[i-1]);
for (auto d : r1) std::cout << d << " "; std::cout << std::endl;
for (auto d : r2) std::cout << d << " "; std::cout << std::endl;
for (auto d : r3) std::cout << d << " "; std::cout << std::endl;
4 5 6
4
5 5