过滤列表中的一个元素

时间:2017-01-25 22:33:30

标签: r list filtering subset

我有一个清单:

name_lst <- list(one = c("John", "Paul", "Ringo", "Kramer"), 
                 two = c("Jerry", "Kramer", "George", "Elaine"))

我想删除&#34; Kramer&#34;来自name_lst[[SOME_VECTOR]],但返回列表的其余部分。希望输出为:

name_lst
$one
[1] "John"  "Paul" "Ringo"
$two
[1] "Jerry"  "Kramer"  "George"  "Elaine"

理想情况下,我可以删除一整套名字,而不只是&#34; Kramer&#34; (例如! %in% c("George", "Kramer")。我试过了:

name_lst[name_lst[1] != "Kramer"]
name_lst[name_lst[[1]] != "Kramer"]
name_lst[name_lst$one != "Kramer"]
name_lst[!(name_lst$one %in% "Kramer")]
name_lst[[name_lst[1] != "Kramer"]]
name_lst[[name_lst[[1]] != "Kramer"]]
name_lst[[name_lst$one != "Kramer"]]
name_lst[[!(name_lst$one %in% "Kramer")]]

这些都会返回错误或相同的列表而不做任何更改。

2 个答案:

答案 0 :(得分:4)

您可以指定要在其中查看的元素,然后过滤并重新分配给该特定列表元素:

name_lst[["one"]] <- 
    name_lst[["one"]][!(name_lst[["one"]] %in% c("Kramer", "SomeoneElse"))]

name_lst
#$one
#[1] "John"   "Paul"   "Ringo"  
#
#$two
#[1] "Jerry"  "Kramer"  "George" "Elaine"  

如果在注释中,您不想执行重新分配但想要获取新对象,则使用purrr::map_if是一种方法。

library(purrr)
NEW_NAME <- name_lst %>%
    map_if(.p = names(.) == "two", ~ .[!(. %in% c("Kramer", "SomeoneElse"))])
# OR, without pipes:
NEW_NAME <- map_if(name_lst,
                   names(name_lst) == "two",
                   ~ .x[!(.x %in% c("Kramer", "SomeoneElse"))])

答案 1 :(得分:0)

对于@ Jota的回答并没有多大帮助,只是一种不同的方式。如果要指定要处理的元素/元素,并且可以选择对多个元素执行此操作,则可以使用lapply,但仅适用于特定元素。

添加第三个列表项,这样我们就可以处理两个元素,而不是一个元素。

name_lst <- list(one = c("John", "Paul", "Ringo", "Kramer"), 
                 two = c("Jerry", "Kramer", "George", "Elaine"),
                 three = c("John", "Paul", "Ringo", "Kramer", "George"))

首先设置参数,因为我认为代码往往会以这种方式读取更好。

names <- c( "George", "Kramer" )
elements <- c( 1, 3 )

names过滤器应用于列表的指定elements

library( magrittr )

name_lst[ elements ] %<>%
  lapply( function(x) x[!( x %in% names )] )

输出:

name_lst
# $one
# [1] "John"  "Paul"  "Ringo"
# 
# $two
# [1] "Jerry"  "Kramer" "George" "Elaine"
# 
# $three
# [1] "John"  "Paul"  "Ringo"