我的Rcpp功能有问题。我基本上有一个数据框(尺寸N*K
)和一个数字向量(尺寸H < N
)作为输入,作为输出我想要返回一个数据框(尺寸H * M
)具有相同的整数向量的行索引。
数据框:
val1 val2 val3 val4
1 0.2059 A 14
2 0.5700 B 61
3 0.5354 C 24
4 0.8123 D 78
5 0.7542 E 39
6 0.6433 F 17
7 0.2452 G 96
8 0.2557 H 93
9 0.7208 I 36
10 0.2565 L 12
INTEGER VECTOR:
2
4
7
10
输出:
2 0.5700 B 61
4 0.8123 D 78
7 0.2452 G 96
10 0.2565 L 12
这是我的代码。在此先感谢您的帮助:
#include <RcppArmadillo.h>
using namespace Rcpp;
// [[Rcpp::export]]
DataFrame matchRows(DataFrame &OriginalDF, NumericVector &ReducedVector)
{
int nr1 = OriginalDF.nrows(), nc1= OriginalDF.size();
int nr2 = ReducedVector.size();
if (nr1 < nr2) throw std::range_error("Size of data frame has to be higher than the target random subset!");
std::map<double, DataFrame> X;
for (int j = 0; j < nr2; j++)
{
NumericVector tmp1=wrap(OriginalDF[ReducedVector[j]]);
tmp1.attr("dim")=Dimension(int(tmp1.size())/nc1,nc1);
DataFrame NewDF(wrap(tmp1));
NewDF.push_back(OriginalDF[ReducedVector[j]]);
NewDF.attr("names")=OriginalDF.attr("names");
X[ReducedVector[j]] = NewDF;
}
return wrap(X);
}
我的代码的先前版本不幸导致RStudio崩溃。理想情况下,有一些方法可以将数据框初始化为零,然后使用push_back()
累加值:
// [[Rcpp::export]]
DataFrame matchRows(DataFrame &OriginalDF, NumericVector &ReducedVector)
{
int nr1 = OriginalDF.nrows(), nc1 = OriginalDF.size();
int nr2 = ReducedVector.size();
if (nr1 < nr2) throw std::range_error("Size of data frame has to be higher than the target random subset!");
DataFrame NewDF;
for (int j = 0; j < nr2; j++)
{
NewDF.push_back(OriginalDF[ReducedVector[j]]);
}
return NewDF;
}
答案 0 :(得分:2)
好的,所以你在这里真正要做的只是在Rcpp中按行ID的data.frame
子集。
e.g。
D[c(2,4,7,10),]
首先,在您的代码中定义:
std::map<double, DataFrame> X;
没有wrap()
转换来处理此类型的对象。此外,在这种情况下真的不应该使用wrap,因为它是由函数指定的返回类型自动转换的。
要有效地对data.frame进行子集化,请不要使用.push_back()
功能,因为它始终需要完整副本,因此效率不高。
相反,您希望使用idx
变量和Rcpp vector subsetting,如下所示:
#include <Rcpp.h>
// Extract rows from data.frame object in Rcpp
// [[Rcpp::export]]
Rcpp::DataFrame matchRows(Rcpp::DataFrame D, Rcpp::IntegerVector idx) {
// First, break apart each vector
Rcpp::IntegerVector val1 = D["val1"];
Rcpp::NumericVector val2 = D["val2"];
Rcpp::CharacterVector val3 = D["val3"];
Rcpp::NumericVector val4 = D["val4"];
// We assume that the index passed in starts at 1.
// Hence, we need to adjust the idx to start at 0 with:
idx = idx - 1;
// Next up, create a new DataFrame Object with selected rows subset.
return Rcpp::DataFrame::create(Rcpp::Named("val1") = val1[idx],
Rcpp::Named("val2") = val2[idx],
Rcpp::Named("val3") = val3[idx],
Rcpp::Named("val3") = val4[idx]
);
}
/*** R
# Make some data
set.seed(1337)
D = data.frame(val1 = 1:10,
val2 = rnorm(10),
val3 = letters[1:10],
val4 = sample(1:100, 10),
stringsAsFactor=FALSE)
# Create index that starts at 1 instead of 0.
# This will be converted in the C++ function.
idx = c(2,4,7,10)
matchRows(D, idx)
*/
详细信息中的恶魔是我们将索引减1,以便在调用索引之前考虑从0开始对R&#39; 1开始的C ++索引。这也可以在C ++代码中处理。但是,我会将其作为一种练习。