벡터 클로닝
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_original을the_copy로 설정하세요.change_negatives_to_zero_with_cloning()의 함수 정의를 완성하여the_copy를the_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)
*/