【问题标题】:Add new column (or filter) based on multiple columns and satisfying multiple conditions基于多个列并满足多个条件添加新列(或过滤器)
【发布时间】:2020-01-30 14:50:36
【问题描述】:

这是“问题”的简化示例

dt <- 
  read.table(textConnection("names age location
Ann  32     Glas
Annie  31       US
Anne  40     Glas
Kerri  31     Edin
David  39      Fra
Glas  29     Annie
Lindsay  24       US
Lynsey  37     Glas
Glas  Annie       US
Lila  39      Fra
Layla  37       US"), 
             header = TRUE, 
             sep = "", 
             stringsAsFactors = FALSE) %>% 
  as_tibble()

我想为同时存在“ann”和“glas”的每一行添加一个名为 AnnGlas 的新列

我知道如何过滤其中一个,但不能同时过滤两个

dt %>% filter_all(any_vars(str_detect(str_to_lower(.), "glas|ann")))

我可以找到一个匹配项,但不能同时使用 apply

apply(dt, 2, function(x) str_detect(str_to_lower(x), "glas|ann"))

我需要找到一些方法来检查任何行列是否包含 glas,以及是否另一个包含 ann,以便我可以创建新列

输出应该是这样的

  names   age   location desc 
   <chr>   <chr> <chr>    <lgl>
 1 Ann     32    Glas     TRUE 
 2 Annie   31    US       FALSE
 3 Anne    40    Glas     TRUE 
 4 Kerri   31    Edin     FALSE
 5 David   39    Fra      FALSE
 6 Glas    29    Annie    TRUE 
 7 Lindsay 24    US       FALSE
 8 Lynsey  37    Glas     FALSE
 9 Glas    Annie US       TRUE 
10 Lila    39    Fra      FALSE
11 Layla   37    US       FALSE

【问题讨论】:

    标签: r multiple-columns multiple-conditions


    【解决方案1】:

    既然我们希望这两个术语都应该存在,我们可以使用lapplyReduce 分别检查它们。如果两列中只有其中一个存在,则将模式一起检查可能会导致输出为TRUE

    dt$desc <- Reduce(`|`, lapply(dt, grepl, pattern = "Glas")) & 
                Reduce(`|`, lapply(dt, grepl, pattern = "Ann"))
    
    dt
    # A tibble: 11 x 4
    #   names   age   location desc 
    #   <chr>   <chr> <chr>    <lgl>
    # 1 Ann     32    Glas     TRUE 
    # 2 Annie   31    US       FALSE
    # 3 Anne    40    Glas     TRUE 
    # 4 Kerri   31    Edin     FALSE
    # 5 David   39    Fra      FALSE
    # 6 Glas    29    Annie    TRUE 
    # 7 Lindsay 24    US       FALSE
    # 8 Lynsey  37    Glas     FALSE
    # 9 Glas    Annie US       TRUE 
    #10 Lila    39    Fra      FALSE
    #11 Layla   37    US       FALSE
    

    【讨论】:

    • 谢谢,这正是我需要的。我唯一改变的是把它变成了tidyverse格式,这样dt就不需要重复3次dt %&gt;% mutate(desc = Reduce(|, lapply(., grepl, pattern = "Glas")) &amp; Reduce(|, lapply(., grepl, pattern = "Ann")))
    猜你喜欢
    • 2020-01-31
    • 2021-12-17
    • 1970-01-01
    • 1970-01-01
    • 2018-02-19
    • 1970-01-01
    • 1970-01-01
    • 2021-01-12
    • 2021-07-15
    相关资源
    最近更新 更多