시작하기무료로 시작하기

벡터 클로닝

R와 달리 C++은 참조에 의한 복사 방식을 사용합니다. 따라서 변수를 복사한 뒤 그 복사본을 변경하면, 원본도 함께 변경됩니다.

// [[Rcpp::export]]
NumericVector always_returns_two(NumericVector x) {
  // 사본 만들기
  NumericVector y = x;
  // 사본 수정
  y[0] = 2;
  // 변경 내용이 원본에도 반영됨
  return x[0];
}

이 동작을 막으려면, clone() 함수를 사용해 원본 변수의 실제 데이터를 새 변수로 복제해야 합니다. 문법은 y = clone(x)입니다. 이 연습 문제에서는 두 개의 함수를 미리 정의해 두었습니다:

  • change_negatives_to_zero(): 숫자형 벡터를 받아 음수를 0으로 바꿔 수정한 뒤, 원본 벡터와 사본을 모두 반환합니다.
  • change_negatives_to_zero_with_cloning(): 위와 동일하지만, 수정하기 전에 원본 벡터를 클로닝합니다.

이 연습은 강의의 일부입니다

Rcpp로 R 코드 최적화하기

강의 보기

연습 안내

  • change_negatives_to_zero()의 함수 정의를 완성하여 the_originalthe_copy로 설정하세요.
  • change_negatives_to_zero_with_cloning()의 함수 정의를 완성하여 the_copythe_original의 클론으로 설정하세요.
  • 콘솔의 출력 내용을 확인하여 각 함수의 결과를 비교하세요.

실습형 인터랙티브 연습

이 예제를 이 샘플 코드를 완성하여 풀어보세요.

#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)
*/
코드 편집 및 실행