【问题标题】:create a logical column for whether a row contains a string in any column为一行是否包含任何列中的字符串创建一个逻辑列
【发布时间】:2021-06-13 15:38:07
【问题描述】:

我有以下数据框:

df <- structure(list(x = c("cc", "aa", "BB", "dd"), y = c("ee", "dd",
"ff", "gg"), z = c("AA", "gg", "bb", "dd")), row.names = c(NA,
-4L), class = c("tbl_df", "tbl", "data.frame"))

我想创建一个二进制列,指示每行是否在任何列中包含“aa”(不区分大小写)。所以在这种情况下,前两个值为 TRUE,最后一个值为 FALSE。如何使用 dplyr 做到这一点?所有答案都解释了如何过滤这些行,而不是如何保留它们

【问题讨论】:

    标签: r dplyr


    【解决方案1】:
    library(tidyverse)
    
    df %>%
      mutate(flag = pmap_lgl(., ~"aa" %in% str_to_lower(c(...))))
    

    rowwise:

    df %>%
      rowwise() %>%
      mutate(flag = "aa" %in% str_to_lower(c_across(everything())))
    

    data.table:

    setDT(df)[, flag := transpose(.SD) %>% map_lgl(~"aa" %in% str_to_lower(.x))]
    

    transpose 来自data.table 包)

    【讨论】:

      【解决方案2】:

      我们也可以这样用:

      library(dplyr)
      
      df %>%
        rowwise() %>%
        mutate(xyz = +any(grepl("aa", cur_data(), ignore.case = TRUE)))
      
      # A tibble: 4 x 4
      # Rowwise: 
        x     y     z       xyz
        <chr> <chr> <chr> <int>
      1 cc    ee    AA        1
      2 aa    dd    gg        1
      3 BB    ff    bb        0
      4 dd    gg    dd        0
      

      在基础 R 中我们也可以这样做:

      Reduce(`+`, apply(df, 1, \(x) +(grepl("aa", x, , ignore.case = TRUE))) |>
               t() |>
               as.data.frame()) -> df$xyz
      
      # A tibble: 4 x 4
      # Rowwise: 
        x     y     z       xyz
        <chr> <chr> <chr> <int>
      1 cc    ee    AA        1
      2 aa    dd    gg        1
      3 BB    ff    bb        0
      4 dd    gg    dd        0
      

      【讨论】:

      • 要使 Anoushiravan 的解决方案不区分大小写,请根据问题添加“ignore.case”: mutate(xyz = +any(grepl("aa", cur_data(), ignore.case = TRUE) ))
      • 哦,我刚刚编辑了我的解决方案以区分大小写!我不知道它应该反过来。谢谢。
      【解决方案3】:

      我们可以使用带有if_any的矢量化选项

      library(dplyr)
      library(stringr)
      df %>%
           mutate(xyz = +(if_any(everything(), 
               ~ str_detect(., regex('aa', ignore_case = TRUE)))))
      

      -输出

      # A tibble: 4 x 4
        x     y     z       xyz
        <chr> <chr> <chr> <int>
      1 cc    ee    AA        1
      2 aa    dd    gg        1
      3 BB    ff    bb        0
      4 dd    gg    dd        0
      

      【讨论】:

        猜你喜欢
        • 2014-10-08
        • 2020-08-09
        • 1970-01-01
        • 1970-01-01
        • 2021-11-22
        • 1970-01-01
        • 2012-11-15
        • 1970-01-01
        • 2023-02-01
        相关资源
        最近更新 更多