開始使用免費開始

向量複製(cloning)

與 R 不同,C++ 採用「引用複製」(copy by reference)的系統。也就是說,當你複製一個變數並在複本上做變更時,原始變數也會一併被改到。

// [[Rcpp::export]]
NumericVector always_returns_two(NumericVector x) {
  // Make a copy
  NumericVector y = x;
  // Modify the copy
  y[0] = 2;
  // The changes also happen in the original
  return x[0];
}

若要避免這種情況,你必須使用 clone() 函式,將原始變數底層的資料複製到新變數中。語法為 y = clone(x)。 在這個練習中,我們已為你定義了兩個函式:

  • change_negatives_to_zero():接收一個數值向量,將其中的負數改為 0,然後同時回傳原始向量與複本。
  • change_negatives_to_zero_with_cloning():與上面相同,但在修改前會先對原始向量進行 clone。

本練習屬於課程

用 Rcpp 最佳化 R 程式碼

檢視課程

練習說明

  • 完成 change_negatives_to_zero() 的函式定義,將 the_original 指派給 the_copy
  • 完成 change_negatives_to_zero_with_cloning() 的函式定義,將 the_copy 指派為 the_original 的 clone。
  • 讀取主控台的內容,比較兩個函式的輸出。

動手互動練習

試著完成這個範例程式碼,體驗一下這個練習。

#include 
using namespace Rcpp;

// [[Rcpp::export]]
List change_negatives_to_zero(NumericVector the_original) {
  // Set the copy to the original
  NumericVector the_copy = ___;
  int n = the_original.size();
  for(int i = 0; i < n; i++) {
    if(the_copy[i] < 0) the_copy[i] = 0;
  }
  return List::create(_["the_original"] = the_original, _["the_copy"] = the_copy);
}

// [[Rcpp::export]]
List change_negatives_to_zero_with_cloning(NumericVector the_original) {
  // Clone the original to make the copy
  NumericVector the_copy = ___;
  int n = the_original.size();
  for(int i = 0; i < n; i++) {
    if(the_copy[i] < 0) the_copy[i] = 0;
  }
  return List::create(_["the_original"] = the_original, _["the_copy"] = the_copy);
}

/*** R
x <- c(0, -4, 1, -2, 2, 4, -3, -1, 3)
change_negatives_to_zero(x)
# Need to define x again because it's changed now
x <- c(0, -4, 1, -2, 2, 4, -3, -1, 3)
change_negatives_to_zero_with_cloning(x)
*/
編輯並執行程式碼