使用正则表达式选择多个列

时间:2018-02-13 22:12:00

标签: r select grep

我的变量名称为r1a r3c r5e r7g r9i r11k r13g r15i等。我正在尝试selectr5 - r12开头的变量并在R中创建数据框。

我可以编写的最佳代码是

data %>% select(grep("r[5-9][^0-9]" , names(data), value = TRUE ),
grep("r1[0-2]", names(data), value = TRUE))

鉴于我对正则表达式的使用经历了一天,我想知道是否有人可以帮助我为此编写更好更紧凑的代码!

3 个答案:

答案 0 :(得分:2)

假设下面的代码x代表您的names(data)。然后以下将做你想要的。

# The names of 'data'
x <- scan(what = character(), text = "r1a r3c r5e r7g r9i r11k r13g r15i")

y <- unlist(strsplit(x, "[[:alpha:]]"))
y <- as.numeric(y[sapply(y, `!=`, "")])
x[y > 4]
#[1] "r5e"  "r7g"  "r9i"  "r11k" "r13g" "r15i"

编辑。

您可以通过上述代码的泛化来创建一个函数。这个函数有三个参数,第一个是变量名称的向量,第二个和第三个是你想要保留的数字的限制。

var_names <- function(x, from = 1, to = Inf){
    y <- unlist(strsplit(x, "[[:alpha:]]"))
    y <- as.integer(y[sapply(y, `!=`, "")])
    x[from <= y & y <= to]
}

var_names(x, 5)
#[1] "r5e"  "r7g"  "r9i"  "r11k" "r13g" "r15i"

答案 1 :(得分:2)

这是一个可以同时获取所有列的正则表达式:

data %>% select(grep("r([5-9]|1[0-2])", names(data), value = TRUE))

竖条表示&#39;或&#39;。

正如评论所指出的那样,r51等项目会失败,也可以缩短。相反,你需要一个稍长的正则表达式:

data %>% select(matches("r([5-9]|1[0-2])([^0-9]|$)"))

答案 2 :(得分:1)

删除非数字,扫描余数并检查每个是否在5:12:

DF <- data.frame(r1a=1, r3c=2, r5e=3, r7g=4, r9i=5, r11k=6, r13g=7, r15i=8) # test data

DF[scan(text = gsub("\\D", "", names(DF)), quiet = TRUE) %in% 5:12]
##   r5e r7g r9i r11k
## 1   3   4   5    6

使用magrittr它也可以这样写:

library(magrittr)

DF %>% .[scan(text = gsub("\\D", "", names(.)), quiet = TRUE) %in% 5:12]
##   r5e r7g r9i r11k
## 1   3   4   5    6