我正在尝试从R转换为c ++编码。如果您选择不赞成这个问题,至少请给我一个答案,以使我学到一些东西。我的问题是,一旦我将数据传递给c ++,我应该如何在c ++中进行逐行计算?从概念上讲,我了解到,一旦我通过c ++一个数据帧,c ++就会将每一列视为自己必须明确命名的向量。我遇到麻烦的地方是设置一个for循环,一次遍历所有向量的相同位置,从而在功能上模拟R中的逐行函数。我也想将此问题扩展到以下应用程序:
如何设置一个循环遍历行范围的循环,从而实现滑动窗口功能?像这样:
## an example of a for loop in R that I want to recapitulate in c++
output <- list()
for(i in 1:nrow(df)){
end_row <- i+3
df_tmp <- df[i:end_row, ]
## do some function here
output[[i]] <- list(df_tmp)
}
如何在问题3中设置相同的滚动函数,但是以允许我有条件地扩展矢量长度的方式?在R中,我编写了使用apply的函数,该函数在一定范围的行上进行迭代,然后返回新数据帧的列表,然后将其转换为大数据帧。从概念上讲,一次对这个向量进行一次处理现在对我来说很困惑。
让我们说我在R中有这个数据框
#example data
a <- c(0, 2, 4, 6, 8, 10)
b <- c(1, 3, 5, 7, 9, 11)
c <- c("chr1", "chr1", "chr1", "chr1", "chr1", "chr1")
d <- c(10.2, 10.2, 4.3, 4.3, 3.4, 7.9)
e <- c("a", "t", "t", "g", "c", "a")
df <- data.frame(a, b, c, d, e)
在c ++中,我已经走了这么远:
#include <algorithm>
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
DataFrame modifyDataFrame(DataFrame df) {
// access the columns
IntegerVector a = df["a"];
IntegerVector b = df["b"];
CharacterVector c = df["c"];
IntegerVector d = df["d"];
CharacterVector e = df["e"];
// write the for loop. I'm attempting to define a single
//position and then apply it to all vectors...
//but no versions of this approach have worked.
for(int i=0; i < a.length(); ++i){
// do some function
}
// return a new data frame
return DataFrame::create(_["a"]= a, _["b"]= b, _["c"]= c, _["d"]= d, _["e"]=e);
}
我一直在关注“高级R”部分。我努力掌握的部分是多向量四循环构造以及如何定义范围迭代器。根据我的代码,这也是您的解释吗?我是否需要为每个向量创建一个迭代器,还是可以仅根据一个向量的长度定义一个位置,然后将其应用于所有向量?
对我来说,最简单的方法就是看一个例子。一旦看到了功能代码的示例,就可以应用我一直在阅读的概念。
编辑:是否可以在RCPP文档中添加类似的示例?我想象很多人在这一步都在挣扎。考虑到数据框是最常见的r数据容器之一,我认为将通过另外两个数据框示例来大大增强rcpp文档-乍一看,概念上的转换并不容易。
答案 0 :(得分:2)
我不认为从这里使用C ++可以提高性能。但是,如果您有一组长度相等的向量(data.frame
保证),则可以简单地使用一个索引进行迭代:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
DataFrame modifyDataFrame(DataFrame df) {
// access the columns
IntegerVector a = df["a"];
IntegerVector b = df["b"];
CharacterVector c = df["c"];
NumericVector d = df["d"];
CharacterVector e = df["e"];
for(int i=0; i < df.nrow(); ++i){
a(i) += 1;
b(i) += 2;
c(i) += "c";
d(i) += 3;
e(i) += "e";
}
// return a new data frame
return DataFrame::create(_["a"]= a, _["b"]= b, _["c"]= c, _["d"]= d, _["e"]=e);
}
/*** R
a <- c(0, 2, 4, 6, 8, 10)
b <- c(1, 3, 5, 7, 9, 11)
c <- c("chr1", "chr1", "chr1", "chr1", "chr1", "chr1")
d <- c(10.2, 10.2, 4.3, 4.3, 3.4, 7.9)
e <- c("a", "t", "t", "g", "c", "a")
df <- data.frame(a, b, c, d, e)
modifyDataFrame(df)
*/
结果:
> modifyDataFrame(df)
a b c d e
1 1 3 chr1c 13.2 ae
2 3 5 chr1c 13.2 te
3 5 7 chr1c 7.3 te
4 7 9 chr1c 7.3 ge
5 9 11 chr1c 6.4 ce
6 11 13 chr1c 10.9 ae
在这里,我使用的是nrow()
类的DataFrame
方法,参见the Rcpp API。就像length()
方法一样,它使用R的C API。我只是发现使用DataFrame方法比选择其中一个向量来检索长度更合乎逻辑。结果将是相同的。
对于滑动窗口,我将首先研究RcppRoll
包。