逐行迭代导入的数据帧中的向量
Iterate over vectors from an imported dataframe row-wise
我正在尝试从 R 切换到 C++ 编码。如果您选择对这个问题投反对票,至少请给我一个答案,这样我就可以学到一些东西。我的问题是,一旦我通过 C++ 数据框,我应该如何在 C++ 中进行逐行计算?从概念上讲,我知道一旦我向 c++ 传递一个数据框,c++ 就会将每一列视为我必须明确命名的自己的向量。我遇到问题的地方是设置一个 for 循环以一次遍历所有向量的相同位置,从而在功能上模拟 R 中的行函数。我想将这个问题扩展到以下应用程序:
- 我将如何设置一个遍历行和 return 向量的循环。就像 R 中的 rowsum 一样?在使用矩阵的高级 R 中有一个这样的例子,但命名法并没有转化为来自数据帧的堆向量。
- 我将如何设置一个循环遍历一行并更改每行中的值,以及 return 修改后的向量?
我如何设置一个循环,一次遍历一系列行,从而实现滑动 window 函数?像这样:
## 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 迭代一系列行的函数,然后 return 一个新数据帧列表,然后我将其转换为一个大数据帧。目前,一次做一个向量在概念上让我感到困惑。
假设我在 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 文档中添加一些这样的示例?我想很多人都在这一步挣扎。考虑到 dataframe 是最常见的 r 数据容器之一,我认为 rcpp 文档将通过更多的 dataframe 示例得到极大的加强——概念上的转换乍一看并不简单。
我不相信你会从这里转到 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
这里我使用的是DataFrame
class、c.f的nrow()
方法。 the Rcpp API。这使用 R 的 C API,就像 length()
方法一样。我只是发现使用 DataFrame 方法比挑出一个向量来检索长度更合乎逻辑。结果是一样的。
至于滑动 window 我会先查看 RcppRoll
包。
我正在尝试从 R 切换到 C++ 编码。如果您选择对这个问题投反对票,至少请给我一个答案,这样我就可以学到一些东西。我的问题是,一旦我通过 C++ 数据框,我应该如何在 C++ 中进行逐行计算?从概念上讲,我知道一旦我向 c++ 传递一个数据框,c++ 就会将每一列视为我必须明确命名的自己的向量。我遇到问题的地方是设置一个 for 循环以一次遍历所有向量的相同位置,从而在功能上模拟 R 中的行函数。我想将这个问题扩展到以下应用程序:
- 我将如何设置一个遍历行和 return 向量的循环。就像 R 中的 rowsum 一样?在使用矩阵的高级 R 中有一个这样的例子,但命名法并没有转化为来自数据帧的堆向量。
- 我将如何设置一个循环遍历一行并更改每行中的值,以及 return 修改后的向量?
我如何设置一个循环,一次遍历一系列行,从而实现滑动 window 函数?像这样:
## 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 迭代一系列行的函数,然后 return 一个新数据帧列表,然后我将其转换为一个大数据帧。目前,一次做一个向量在概念上让我感到困惑。
假设我在 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 文档中添加一些这样的示例?我想很多人都在这一步挣扎。考虑到 dataframe 是最常见的 r 数据容器之一,我认为 rcpp 文档将通过更多的 dataframe 示例得到极大的加强——概念上的转换乍一看并不简单。
我不相信你会从这里转到 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
这里我使用的是DataFrame
class、c.f的nrow()
方法。 the Rcpp API。这使用 R 的 C API,就像 length()
方法一样。我只是发现使用 DataFrame 方法比挑出一个向量来检索长度更合乎逻辑。结果是一样的。
至于滑动 window 我会先查看 RcppRoll
包。