声明类似于which()的S4对象列表

时间:2016-06-08 16:15:33

标签: r s4 which

我有一个mem.shapes类对象列表SpatialPolygonsDataFrame。每个列表元素都包含一个插槽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 - 类似的语句可以“到达”列表元素的@data槽内以返回索引{{ 1}}有i

如果之前已经回答过道歉;尽管搜索,我仍无法找到它。我很感激帮助使我的问题更加通用和更具可搜索性,因为我认为这一定是一个相当普遍的问题。

1 个答案:

答案 0 :(得分:1)

您可以使用应用功能查找匹配项。

首先让我们创建一些S4数据来测试它。为简单起见,我将使用返回S4类的Matrix包。

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

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

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