类似于 which() 的语句用于 S4 对象列表

Statement similar to which() for a list of S4 objects

我有 class SpatialPolygonsDataFrame 个对象的列表 mem.shapes。每个列表元素包含一个插槽 mem.shapes[[i]]@data,这是一个包含列 mem.shapes[[i]]@data$SCINAME.

的数据框

我想提取 mem.shapes 中在 mem.shapes[[i]]@data$SCINAME[1] 中具有特定字符串的元素。下面的代码给出了我想要的:

SCINAME <- vector(mode="character", length=length(mem.shapes))
for(i in 1:length(mem.shapes)){
    SCINAME[i] <- as.character(mem.shapes[[i]]@data$SCINAME[1])
}
which(SCINAME=="Dendroica magnolia")

但我想有一种更简洁的方法可以做到这一点——某种类似 which 的语句可以 "reach inside" 列表元素的 @data 槽 return 具有 mem.shapes[[i]]@data$SCINAME[1]=="Dendroica magnolia"

的索引 i

如果之前已经回答过这个问题,我们深表歉意;尽管搜索,我还是找不到它。如果能帮助我使我的问题更笼统和更易于搜索,我将不胜感激,因为我认为这一定是一个相当普遍的问题。

您可以使用应用函数来查找匹配项。

首先让我们创建一些 S4 数据来测试它。为简单起见,我将使用 returns S4 类.

的 Matrix 包
library(Matrix)
set.seed(123)
m <- Matrix(sample(1:6, 100, replace=T) ,ncol = 10,sparse = T)

现在使用 sapply 查找等于 5 的 m@x 值

unlist(sapply(1:length(m@x), function(i) {if(m@x[i]==5) i}))
# [1]  2 13 22 26 33 34 37 53 58 65 67 68 69 71 73 82 84 97

请注意,当然,在这个简单的示例中 which(m@x==5) 就可以达到目的。但是这种方法可以外推到 OP 在更复杂的 S4 结构中向下钻取级别的示例。例如。以下应该适用于 OP 数据(尽管由于未提供数据而未测试)。

unlist(sapply(1:length(mem.shapes), function(i) {
  if(as.character(mem.shapes[[i]]@data$SCINAME[1])=="Dendroica magnolia") i}))

为方便起见,您可以将其包装在一个函数中

which.i <- function(i, expr) {
  unlist(sapply(i, function(i) {if(eval(parse(text=expr))) i}))
}

which.i(1:length(m@x), "m@x[i]==5")
# [1]  2 13 22 26 33 34 37 53 58 65 67 68 69 71 73 82 84 97