удалить элементы из списка значений на основе SpatialLinesDataFrames в числовом векторе - PullRequest
2 голосов
/ 18 апреля 2019

У меня есть список объектов SpatialLinesDataFrame, и я хочу удалить элементы списка, у которых значение содержит столбец data.frame, равный одному из значений в простом числовом векторе.Я хочу повторить этот процесс, поскольку фактический список огромен.Вот упрощенный пример данных с циклом, который не выполняет то, что я хочу, чтобы он делал:

#create list of single-feature SpatialLineDataFrame
library(raster)

l1 <- cbind(c(0,3), c(0,3))
l2 <- cbind(c(0, 13), c(0, 1))
l3 <- cbind(c(0, 24), c(0,22.5))
l4 <- cbind(c(0, 1), c(0,13))
l5 <- cbind(c(0, 6), c(0,6))
Sldf <- spLines(l1, l2, l3, l4, l5, attr=data.frame(lineID=1:5))
linel <- lapply(1:5, function(i) Sldf[i,])
#numeric vector
x <- c(1,3,5)

newlist <- list()
for (i in 1:length(linel)){
  if (linel[[i]]@data$lineID == x) {
    newlist[[i]] <- linel[[i]]
  }
}

Я получаю следующее сообщение об ошибке:

Предупреждение: 1: Вif (linel [[i]] @ data $ lineID == x) {: условие имеет длину> 1, и будет использоваться только первый элемент

Но я хочу удалить списокэлементы с lineID == 1 или 3 или 5 (только совпадают с индексом # в примере) из списка и заканчиваются на:

newlist

[[1]]
class       : SpatialLinesDataFrame 
features    : 1 
extent      : 0, 13, 0, 1  (xmin, xmax, ymin, ymax)
coord. ref. : NA 
variables   : 1
names       : lineID 
value       :      2 

[[2]]
class       : SpatialLinesDataFrame 
features    : 1 
extent      : 0, 13, 0, 1  (xmin, xmax, ymin, ymax)
coord. ref. : NA 
variables   : 1
names       : lineID 
value       :      4

1 Ответ

1 голос
/ 18 апреля 2019

Вы можете использовать sapply из базы R и извлекать lineID из каждого linel, а затем сохранять только те, которых нет в x.

linel[!sapply(linel, function(data) data$lineID) %in% x]


#[[1]]
#class       : SpatialLinesDataFrame 
#features    : 1 
#extent      : 0, 13, 0, 1  (xmin, xmax, ymin, ymax)
#coord. ref. : NA 
#variables   : 1
#names       : lineID 
#value       :      2 

#[[2]]
#class       : SpatialLinesDataFrame 
#features    : 1 
#extent      : 0, 1, 0, 13  (xmin, xmax, ymin, ymax)
#coord. ref. : NA 
#variables   : 1
#names       : lineID 
#value       :      4 

Еще несколько методов, использующих purrr

purrr::discard(linel, ~ .$lineID %in% x)
purr::keep(linel, ~ ! .$lineID %in% x)

Что касается вашего цикла for, вы проверяете значение с помощью ==. Поскольку x является вектором значений, а не одно значение, используя ==, выдается предупреждение, что оно использует только первое значение из x. Вместо этого вы хотите сделать это с %in%, поскольку в x есть несколько значений. Тем не менее, использование %in% вернет вектор значений TRUE / FALSE, которые вы должны обернуть в any. Более того, даже после всех этих изменений код сохраняет эти элементы списка с lineID в x в newlist и не удаляет их из linel. Так что вам может понадобиться

newlist <- list()
j <- 1
for (i in 1:length(linel)){
   if (!any(linel[[i]]$lineID %in% x)) {
       newlist[[j]] <- linel[[i]]
       j = j + 1
    }
}

и теперь newlist - это список, который вы хотите.

...