R - 向量值的子集列表 data.frames
R - subset list data.frames by vector values
我有一个 SpatialLinesDataFrames
的列表,并希望根据将这些值与数值向量中的值进行比较来对列表进行子集化。
具体来说,我想删除 data.frame 的特定列 ('lineID') 中向量中包含的值之一的列表元素。可重现的例子:
#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))
sldfl <- list()
sldfl[[1]] <- Sldf[1,]
sldfl[[2]] <- Sldf[2,]
sldfl[[3]] <- Sldf[3,]
sldfl[[4]] <- Sldf[4,]
sldfl[[5]] <- Sldf[5,]
#create numeric vector
m <- c(1,3,5,7,10)
#attempt to keep only list elements that are not equal to any
#of the values contained in vector
final <- list()
for (i in 1:length(sldfl)) {
for (j in 1:length(m)) {
if (factor(sldfl[[i]]@data$lineID) != m[j]) {
final[[i]] <- sldfl[[i]]
}}}
循环的结果returns整个原始列表。我的循环有什么问题?
你基本上有两个向量,ids
和 m
:
> ids
[1] 1 2 3 4 5
> m
[1] 1 3 5 7 10
并且 运行 本质上是这样的:
for(i in 1:length(ids)){
for(j in 1:length(m)){
if(i != m[j]){
message("add ",i,j)
}else{
message("Not adding ",i,j)
}
}
}
运行 你会看到它添加了很多元素,因为你正在用 m
中的每个元素测试每个 ID,而 m
中至少有一个元素不是在 ID 中,以便添加一个(或多个)。
你真正想要的似乎是:
for(i in 1:length(ids)){
if(!(i %in% m)){
message("add ",i,j)
}else{
message("Not adding ",i,j)
}
}
打印:
Not adding 15
add 25
Not adding 35
add 45
Not adding 55
添加 ID 为 2 和 4 的元素,这些元素不在 m
中。
或者,使用基本 R Filter
函数,通过列表元素上的函数减少列表:
> Filter(function(L){!(L@data$lineID %in% m)}, sldfl)
[[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
我有一个 SpatialLinesDataFrames
的列表,并希望根据将这些值与数值向量中的值进行比较来对列表进行子集化。
具体来说,我想删除 data.frame 的特定列 ('lineID') 中向量中包含的值之一的列表元素。可重现的例子:
#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))
sldfl <- list()
sldfl[[1]] <- Sldf[1,]
sldfl[[2]] <- Sldf[2,]
sldfl[[3]] <- Sldf[3,]
sldfl[[4]] <- Sldf[4,]
sldfl[[5]] <- Sldf[5,]
#create numeric vector
m <- c(1,3,5,7,10)
#attempt to keep only list elements that are not equal to any
#of the values contained in vector
final <- list()
for (i in 1:length(sldfl)) {
for (j in 1:length(m)) {
if (factor(sldfl[[i]]@data$lineID) != m[j]) {
final[[i]] <- sldfl[[i]]
}}}
循环的结果returns整个原始列表。我的循环有什么问题?
你基本上有两个向量,ids
和 m
:
> ids
[1] 1 2 3 4 5
> m
[1] 1 3 5 7 10
并且 运行 本质上是这样的:
for(i in 1:length(ids)){
for(j in 1:length(m)){
if(i != m[j]){
message("add ",i,j)
}else{
message("Not adding ",i,j)
}
}
}
运行 你会看到它添加了很多元素,因为你正在用 m
中的每个元素测试每个 ID,而 m
中至少有一个元素不是在 ID 中,以便添加一个(或多个)。
你真正想要的似乎是:
for(i in 1:length(ids)){
if(!(i %in% m)){
message("add ",i,j)
}else{
message("Not adding ",i,j)
}
}
打印:
Not adding 15
add 25
Not adding 35
add 45
Not adding 55
添加 ID 为 2 和 4 的元素,这些元素不在 m
中。
或者,使用基本 R Filter
函数,通过列表元素上的函数减少列表:
> Filter(function(L){!(L@data$lineID %in% m)}, sldfl)
[[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