从数值向量中的基于SpatialLinesDataFrames的值列表中删除元素

时间:2019-04-18 02:15:16

标签: r list loops sp

我有一个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 个答案:

答案 0 :(得分:1)

您可以使用基数R中的sapply并从每个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的{​​{1}}中,而不将其从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 } } 是您想要的列表。