2016-06-08 10 views
1

У меня есть список mem.shapes объектов класса SpatialPolygonsDataFrame. Каждый элемент списка содержит слот mem.shapes[[i]]@data, который представляет собой кадр данных, который включает в себя столбец mem.shapes[[i]]@data$SCINAME.Ведомость, аналогичная которой() для списка объектов S4

Я хотел бы извлечь элементы 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, которые имеют mem.shapes[[i]]@data$SCINAME[1]=="Dendroica magnolia"

Извините, если об этом ответили ранее; Я не смог найти его, несмотря на поиск. Я был бы признателен за то, что мой вопрос стал более общим и более доступным для поиска, поскольку я предполагаю, что это должна быть достаточно распространенная проблема.

ответ

1

Вы можете использовать функции apply, чтобы найти совпадения.

Сначала давайте создадим некоторые данные S4, чтобы проверить это. Для простоты я использую пакет Matrix, который возвращает классы S4.

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

теперь используют sapply найти значения т @ х, которые равны 5

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

Обратите внимание, что, конечно, в этом простом примере which([email protected]==5) бы служили цели. Но этот метод можно экстраполировать на пример OP для сверления уровней в более сложной структуре S4. Например. следующее должно работать над данными ОП (хотя это не проверено, поскольку данные не были предоставлены).

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([email protected]), "[email protected][i]==5") 
# [1] 2 13 22 26 33 34 37 53 58 65 67 68 69 71 73 82 84 97