是否可以在 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

您可以确认的是每个文件中数字的总和。