10

我可以使用 dplyr::select(ends_with) 来选择适合多个条件中的任何一个的列名。考虑到我的列名,我想使用结尾而不是包含或匹配,因为我要选择的字符串在列名的末尾是相关的,但也可能出现在其他的中间。例如,

df <- data.frame(a10 = 1:4,
             a11 = 5:8,
             a20 = 1:4,
             a12 = 5:8)

我想选择以 1 或 2 结尾的列,只有 a11 和 a12 列。select(ends_with) 是最好的方法吗?

谢谢!

4

3 回答 3

8

您也可以使用正则表达式来执行此操作。我知道您最初不想使用匹配项,但如果您使用“字符串结尾”符号,它实际上效果很好$。用 .分隔各种结尾|

df <- data.frame(a10 = 1:4,
                 a11 = 5:8,
                 a20 = 1:4,
                 a12 = 5:8)

df %>% select(matches('1$|2$'))
  a11 a12
1   5   5
2   6   6
3   7   7
4   8   8

如果您有一个包含长列表的更复杂示例,请使用paste0with collapse = '|'

dff <- data.frame(a11 = 1:3,
                  a12 = 2:4,
                  a13 = 3:5,
                  a16 = 5:7,
                  my_cat = LETTERS[1:3],
                  my_dog = LETTERS[5:7],
                  my_snake = LETTERS[9:11])

my_cols <- paste0(c(1,2,6,'dog','cat'), 
                  '$', 
                  collapse = '|')

dff %>% select(matches(my_cols))

  a11 a12 a16 my_cat my_dog
1   1   2   5      A      E
2   2   3   6      B      F
3   3   4   7      C      G
于 2018-01-29T06:05:29.773 回答
5

从版本1.0.0开始,您可以使用布尔逻辑组合多个选择,例如!(negate)、&(and) 和|(or)。

### Install development version on GitHub first until CRAN version is available
# install.packages("devtools")
# devtools::install_github("tidyverse/dplyr")
library(dplyr, warn.conflicts = FALSE)

df <- data.frame(a10 = 1:4,
                 a11 = 5:8,
                 a20 = 1:4,
                 a12 = 5:8)

df %>% 
  select(ends_with("1") | ends_with("2"))
#>   a11 a12
#> 1   5   5
#> 2   6   6
#> 3   7   7
#> 4   8   8

或使用num_range()选择所需的列

df %>% 
  select(num_range(prefix = "a", range = 11:12))
#>   a11 a12
#> 1   5   5
#> 2   6   6
#> 3   7   7
#> 4   8   8

reprex 包于 2020-02-17 创建(v0.3.0)

于 2020-02-17T21:20:49.300 回答
2

我不知道这是否ends_with()是最好的方法,但您也可以在带有逻辑索引的基础 R 中执行此操作。

# Extract the last character of the column names, and test if it is "1" or "2"
lgl_index <- substr(x     = names(df), 
                    start = nchar(names(df)), 
                    stop  = nchar(names(df))) %in% c("1", "2")

使用此索引,您可以按如下方式对数据框进行子集化

df[, lgl_index]
  a11 a12
1   5   5
2   6   6
3   7   7
4   8   8

或与dplyr::select()

select(df, which(lgl_index))
  a11 a12
1   5   5
2   6   6
3   7   7
4   8   8

只保留以 1 或 2 结尾的列。

于 2017-08-21T11:31:09.343 回答