【发布时间】:2017-09-19 13:38:38
【问题描述】:
假设我有一个List,其中包含几个元素(IntegerVector、Numericvector 或 CharacterVector)。因此,我想避免任何复制。
要从我的List 中删除元素,我编写了以下 Rcpp 代码:
void list_remove_element (List x, int i) {
Rcout << "Size before : " << x.size() << endl;
x.erase(i);
Rcout << "Size after : " <<x.size() << endl;
}
在内部,这段代码有效地擦除了相应的代码。遗憾的是,在此函数返回后,R 中没有出现任何变化:
> u = list(a=1:5, b=3:4, c=5:6)
> list_remove_elements (u, 1)
Size before : 3
Size after : 2
> str(u)
List of 3
$ a: int [1:5] 1 2 3 4 5
$ b: int [1:2] 3 4
$ c: int [1:2] 5 6
据我了解,使用函数来扩大或缩小 Rcpp 对象会导致数据从原始对象复制到新对象。有什么办法可以避免这种情况吗?
编辑:
我还尝试了以下操作:
void list_remove_elements (SEXP x) {
SET_VECTOR_ELT(x, 1, R_NilValue);
}
自从我得到它几乎可以工作:
> str(u)
List of 3
$ a: int [1:5] 1 2 3 4 5
$ b: NULL
$ c: int [1:2] 5 6
但我仍然有元素 'b' 并且不确定这是正确的做法......
【问题讨论】:
-
不适用于总是连续向量的 SEXP 类型。现在,向量列表不会复制其向量。仅重新创建顶级列表。
-
参见 Writing R Extensions 手册及其关于内存分析的提示。这可能就是你想要的。
-
为什么不直接使用
u[2] <- NULL? -
让
u[[2]] <- NULL. -
重点是我还有很多其他的函数可以直接修改参数。然后我不使用返回值,我希望这个函数具有相同的行为(出于一致性目的)。假设我有一个我的列表
A。我像这样使用我的其他功能:fct1(A); fct2(A) ;我真的不想做以下事情:fct1(A); A = fct2 (A) ;但也许我误解了你的答案......