【问题标题】:Return full list if element to remove from list is not found如果未找到要从列表中删除的元素,则返回完整列表
【发布时间】:2022-10-15 15:50:51
【问题描述】:

我有一个列表,我可以根据模式的存在从中删除元素(请参阅this 帖子)。

lst <- list(a = 1:4, b = 4:8, c = 8:10)

pattern <- "a|c"
lstnew <- lst[-grep(pattern, names(lst))]

上面的代码从列表中删除元素 a 和 c。伟大的。有时虽然我在列表中没有匹配的模式。然后我希望它返回完整列表。如果我使用上面的代码,它会返回一个空的命名列表。

pattern <- "d|e"
lstnew <- lst[-grep(pattern, names(lst))]

lstnew
named list()

似乎 ifelse() 是实现此目的的合乎逻辑的选择,即如果模式在列表中匹配,则从列表中删除元素,否则返回完整列表。有什么建议么?

【问题讨论】:

  • 无法重现。第二个示例删除元素“c”并返回元素“a”和“b”。
  • 对不起,现在修好了!

标签: r list


【解决方案1】:

使用grepl 获得子集的逻辑向量:

lst <- list(a = 1:4, b = 4:8, c = 8:10)

pattern <- "a|c"
grepl(pattern, names(lst))
#[1]  TRUE FALSE  TRUE
lst[!grepl(pattern, names(lst))]
#$b
#[1] 4 5 6 7 8

pattern <- "d|e"
grepl(pattern, names(lst))
#[1] FALSE FALSE FALSE
lst[!grepl(pattern, names(lst))]
#$a
#[1] 1 2 3 4
#
#$b
#[1] 4 5 6 7 8
#
#$c
#[1]  8  9 10

【讨论】:

    【解决方案2】:

    这是一个否定的问题。当没有匹配项时,grep 返回一个integer(0),因此- 符号不执行任何操作。考虑改用grepl

    lst[!grepl('e|f', names(lst))]
    $a
    [1] 1 2 3 4
    
    $b
    [1] 4 5 6 7 8
    
    $c
    [1]  8  9 10
    

    【讨论】:

    • 和罗兰的答案一样好,所以我也投了这个答案
    • @FlyingDutch Ronald 比我早 17 秒发布。我想这就是为什么赞成票不同的原因。谢谢
    【解决方案3】:

    这是stringr 的另一个可能选项,您可以在其中使用negate

    library(stringr)
    
    lst <- list(a = 1:4, b = 4:8, c = 8:10)
    
    pattern <- "a|c"
    lst[str_subset(names(lst), pattern, negate = T)]
    # $b
    # [1] 4 5 6 7 8
    
    pattern <- "d|e"
    lst[str_subset(names(lst), pattern, negate = T)]
    #$a
    #[1] 1 2 3 4
    
    #$b
    #[1] 4 5 6 7 8
    
    #$c
    #[1]  8  9 10
    

    【讨论】:

      猜你喜欢
      • 2022-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多