是否可以在 R 中的 cppFunction 中动态加载文件?
Is it possible to dynamically load files inside a cppFunction in R?
我正在解决一个问题,如果能够在循环内动态加载保存在磁盘中的向量,我将受益匪浅,因为这允许我跳过即时计算向量(在我的实际过程中一个向量被多次使用,并且作为矩阵的向量集合太大而无法一次全部存储在内存中)。作为一个简化的示例,假设我们将矢量存储在路径为 prefix
的目录中(每个都在其自己的文件中)。这些文件的名称是vec0.txt、vec1.txt、vec2.txt、...等。我们希望对包含范围start
-的所有指定向量的所有数字求和。 end
。所有向量的 size
是已知的并且总是相同的。我想到了类似的东西:
library(Rcpp)
cppFunction('int sumvectors(int start, int end, string prefix, int size) {
int i;
int j;
int arr[size];
int sum=0;
for (i=start; i <= end; i++) {
// Here you would construct the path to the file paste0(prefix, vec, i, ".txt")
// Then load it and put it into an array
for (j=0; j <= size; j++) {
sum+=arr[j];
}
}
return sum;
}')
这样的事情有可能吗?我对 R 还不错,但从未使用过 C 或 C++,所以我什至不知道这是否适用于 Rcpp
是的,这当然是可能的。如果您的数字是用这样的空格分隔的纯文本文件编写的:
C://Users/Administrator/vec1.txt
5.1 21.4 563 -21.2 35.6
C://Users/Administrator/vec2.txt
3 6 8 7 10 135
那么你可以编写如下函数:
cppFunction("
std::vector<float> read_floats(const std::string& path)
{
std::vector<float> result;
for(int i = 1; i < 3; ++i)
{
std::string file_path = path + std::to_string(i) + \".txt\";
std::ifstream myfile(file_path.c_str(), std::ios_base::in);
float a, vec_sum = 0;
std::vector<float> vec;
while(myfile >> a)
{
vec.push_back(a);
}
for(std::vector<float>::iterator it = vec.begin(); it != vec.end(); ++it)
{
vec_sum += *it;
}
result.push_back(vec_sum);
}
return result;
}", include = c("#include<string>", "#include<fstream>", "#include<vector>"))
它创建了一个允许您执行此操作的 R 函数:
read_floats("c:/Users/Administrator/vec")
#> [1] 603.9 169.0
您可以确认的是每个文件中数字的总和。
我正在解决一个问题,如果能够在循环内动态加载保存在磁盘中的向量,我将受益匪浅,因为这允许我跳过即时计算向量(在我的实际过程中一个向量被多次使用,并且作为矩阵的向量集合太大而无法一次全部存储在内存中)。作为一个简化的示例,假设我们将矢量存储在路径为 prefix
的目录中(每个都在其自己的文件中)。这些文件的名称是vec0.txt、vec1.txt、vec2.txt、...等。我们希望对包含范围start
-的所有指定向量的所有数字求和。 end
。所有向量的 size
是已知的并且总是相同的。我想到了类似的东西:
library(Rcpp)
cppFunction('int sumvectors(int start, int end, string prefix, int size) {
int i;
int j;
int arr[size];
int sum=0;
for (i=start; i <= end; i++) {
// Here you would construct the path to the file paste0(prefix, vec, i, ".txt")
// Then load it and put it into an array
for (j=0; j <= size; j++) {
sum+=arr[j];
}
}
return sum;
}')
这样的事情有可能吗?我对 R 还不错,但从未使用过 C 或 C++,所以我什至不知道这是否适用于 Rcpp
是的,这当然是可能的。如果您的数字是用这样的空格分隔的纯文本文件编写的:
C://Users/Administrator/vec1.txt
5.1 21.4 563 -21.2 35.6
C://Users/Administrator/vec2.txt
3 6 8 7 10 135
那么你可以编写如下函数:
cppFunction("
std::vector<float> read_floats(const std::string& path)
{
std::vector<float> result;
for(int i = 1; i < 3; ++i)
{
std::string file_path = path + std::to_string(i) + \".txt\";
std::ifstream myfile(file_path.c_str(), std::ios_base::in);
float a, vec_sum = 0;
std::vector<float> vec;
while(myfile >> a)
{
vec.push_back(a);
}
for(std::vector<float>::iterator it = vec.begin(); it != vec.end(); ++it)
{
vec_sum += *it;
}
result.push_back(vec_sum);
}
return result;
}", include = c("#include<string>", "#include<fstream>", "#include<vector>"))
它创建了一个允许您执行此操作的 R 函数:
read_floats("c:/Users/Administrator/vec")
#> [1] 603.9 169.0
您可以确认的是每个文件中数字的总和。