迭代 S4 对象槽 Rcpp
Iterate over S4 object slots Rcpp
是否可以迭代 S4
个对象槽?
到目前为止,我已经能够想出这个了。但我真的很想避免调用 R 函数 slotNames
。有没有可能在 C/C++ 级别上做同样的事情?
// [[Rcpp::export]]
void foo(SEXP x) {
Rcpp::S4 obj(x);
Function slotNames("slotNames");
CharacterVector snames = slotNames(obj);
for (int i = 0; i < snames.size(); i++) {
SEXP slot = obj.slot(Rcpp::as<std::string>(snames[i]));
// do something with slot
}
}
查看 R source code,我看到了这样的内容:
/**
* R_has_slot() : a C-level test if a obj@<name> is available;
* as R_do_slot() gives an error when there's no such slot.
*/
int R_has_slot(SEXP obj, SEXP name) {
#define R_SLOT_INIT \
if(!(isSymbol(name) || (isString(name) && LENGTH(name) == 1))) \
error(_("invalid type or length for slot name")); \
if(!s_dot_Data) \
init_slot_handling(); \
if(isString(name)) name = installChar(STRING_ELT(name, 0))
R_SLOT_INIT;
if(name == s_dot_Data && TYPEOF(obj) != S4SXP)
return(1);
/* else */
return(getAttrib(obj, name) != R_NilValue);
}
我想这意味着您可以使用 getAttrib
将其拖出。
所以,今天我了解到S4插槽其实只是一些特殊的属性,这些属性可以通过@
访问。观察:
> setClass("Foo", list(apple = "numeric"))
> foo <- new("Foo", apple = 1)
> foo@apple
[1] 1
> attributes(foo)
$apple
[1] 1
$class
[1] "Foo"
attr(,"package")
[1] ".GlobalEnv"
> foo@class
[1] "Foo"
attr(,"package")
[1] ".GlobalEnv"
> attr(foo, "bar") <- 2
> foo@bar
[1] 2
希望这至少能给你一个开始的地方。
是否可以迭代 S4
个对象槽?
到目前为止,我已经能够想出这个了。但我真的很想避免调用 R 函数 slotNames
。有没有可能在 C/C++ 级别上做同样的事情?
// [[Rcpp::export]]
void foo(SEXP x) {
Rcpp::S4 obj(x);
Function slotNames("slotNames");
CharacterVector snames = slotNames(obj);
for (int i = 0; i < snames.size(); i++) {
SEXP slot = obj.slot(Rcpp::as<std::string>(snames[i]));
// do something with slot
}
}
查看 R source code,我看到了这样的内容:
/**
* R_has_slot() : a C-level test if a obj@<name> is available;
* as R_do_slot() gives an error when there's no such slot.
*/
int R_has_slot(SEXP obj, SEXP name) {
#define R_SLOT_INIT \
if(!(isSymbol(name) || (isString(name) && LENGTH(name) == 1))) \
error(_("invalid type or length for slot name")); \
if(!s_dot_Data) \
init_slot_handling(); \
if(isString(name)) name = installChar(STRING_ELT(name, 0))
R_SLOT_INIT;
if(name == s_dot_Data && TYPEOF(obj) != S4SXP)
return(1);
/* else */
return(getAttrib(obj, name) != R_NilValue);
}
我想这意味着您可以使用 getAttrib
将其拖出。
所以,今天我了解到S4插槽其实只是一些特殊的属性,这些属性可以通过@
访问。观察:
> setClass("Foo", list(apple = "numeric"))
> foo <- new("Foo", apple = 1)
> foo@apple
[1] 1
> attributes(foo)
$apple
[1] 1
$class
[1] "Foo"
attr(,"package")
[1] ".GlobalEnv"
> foo@class
[1] "Foo"
attr(,"package")
[1] ".GlobalEnv"
> attr(foo, "bar") <- 2
> foo@bar
[1] 2
希望这至少能给你一个开始的地方。