【问题标题】:Statement similar to which() for a list of S4 objects类似于 which() 的语句,用于 S4 对象列表
【发布时间】:2016-06-08 16:15:32
【问题描述】:

我有一个mem.shapesSpatialPolygonsDataFrame 的对象列表。每个列表元素都包含一个槽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 槽以返回具有@ 的索引i 987654331@

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

【问题讨论】:

    标签: r s4


    【解决方案1】:

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

    首先让我们创建一些 S4 数据来测试它。为简单起见,我将使用返回 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-28
      • 1970-01-01
      • 2018-11-24
      • 2018-07-04
      • 2021-09-04
      • 1970-01-01
      相关资源
      最近更新 更多