【问题标题】:Select column if it contains text?选择列是否包含文本?
【发布时间】:2020-11-15 23:34:58
【问题描述】:

在使用包含不同数据类型和名称的多列的 R tibble 时,如何正确使用 dplyr 包中的 select_if 来仅选择包含文本的列?

例如一个小标题tib,比如这个:

+----------+------------+------------+-------+
| PersonID | EmployeeID |    Date    | Value |
+----------+------------+------------+-------+
|      123 | abc        | 10/12/2020 |  33.4 |
|      345 | fff        | 10/13/2020 |  44.2 |
|      567 | ddg        | 11/1/2020  |  60.2 |
+----------+------------+------------+-------+

如何使用select_if 仅选择 PersonID 和 EmployeeID 列?

到目前为止,我已经尝试了以下方法:

tib %>% select_if(~ grepl("ID", .))

但是,我收到以下错误:

Error: `.p` is invalid.
x `.p` should return a single logical.
i `.p` returns a size 2000 <logical> for column `PersonID`.

contains的使用方法正确吗?

我知道tib %&gt;% select_if(is.character) 可以工作,但是如何编写与is.character 类似的函数来检测列标题中的字符串?

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    如果我们想根据列名模式select 列,请使用select_helpers。基于 'ID' 的出现,似乎 OP 想要选择列名中 ends_with 'ID' 子字符串的列

    library(dplyr)
    tib %>%
          select(ends_with('ID'))
    

    如果列名在任何地方都有“ID”

    tib %>%
        select(contains('ID'))
    

    或者对于复杂的正则表达式,使用matches

    tib %>%
       select(matches("^[PE].*ID"))
    

    使用dplyr 版本&gt;= 1.0,我们可以使用acrossselect

    tib %>%
       select(where(is.character))
    # A tibble: 3 x 2
    #  EmployeeID Date      
    #  <chr>      <chr>     
    #1 abc        10/12/2020
    #2 fff        10/13/2020
    #3 ddg        11/1/2020 
    

    注意:这里,它正在检查列值的typeselect 那些。同样,如果我们需要选择具有特定值的列,我们可以使用

    tib %>%
        select(where(~ any(. == 'fff')))
    # A tibble: 3 x 1
    #  EmployeeID
    #  <chr>     
    #1 abc       
    #2 fff       
    #3 ddg     
    

    数据

    tib <- structure(list(PersonID = c(123, 345, 567), EmployeeID = c("abc", 
    "fff", "ddg"), Date = c("10/12/2020", "10/13/2020", "11/1/2020"
    ), Value = c(33.4, 44.2, 60.2)), row.names = c(NA, -3L), class = c("tbl_df", 
    "tbl", "data.frame"))
    

    【讨论】:

      【解决方案2】:

      在base R中,你可以使用grepl/grep来使用正则表达式:

      tib[grepl('ID', names(tib))]
      #With grep
      #tib[grep('ID', names(tib))]
      #  PersonID EmployeeID
      #     <dbl> <chr>     
      #1      123 abc       
      #2      345 fff       
      #3      567 ddg   
      

      如果值'ID' 总是在末尾,我们也可以使用endsWith

      tib[endsWith(names(tib), 'ID')]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-03-04
        • 1970-01-01
        • 1970-01-01
        • 2021-10-27
        • 2013-06-23
        • 2013-10-04
        • 2011-02-16
        • 1970-01-01
        相关资源
        最近更新 更多