2014-08-30 59 views
1

我想grep列名并保持精确匹配。我无法避免部分匹配。这是一个更复杂用例的简单例子。避免grep中的部分匹配

keep <- c("A", "AA", "B") # I get this dynamically in my actual use case 
mydata <- data.frame(A=c(1, 1, 1), 
        AA=c(1, 1, 1), 
        B=c(1, 1, 1), 
        BB=c(1, 1, 1), 
        C=c(1, 1, 1)) 

pattern <- paste(keep, collapse = "|") 
mydata.subset <- mydata[grep(pattern, colnames(mydata), value=TRUE)] 
names(mydata.subset) 
# [1] "A" "AA" "B" "BB" 

Bkeep,但不BB。如何在不诉诸明确指定BB的方法的情况下排除部分匹配如BB?我很犹豫要求只有grep()的例子,但我认为我需要,因为我的实际情况更复杂,并且基于grep()解决方案。

也试过

mydata.subset <- mydata[grep(pattern, colnames(mydata), fixed=TRUE)] 
names(mydata.subset) 
# character(0) 
+2

你知道你可以做'mydata [keep]'? – flodel 2014-08-30 14:15:06

+1

@ flodel:+1唯一的区别是它不保留原始的列顺序(也许'保持'向量可以随机排序...) – digEmAll 2014-08-30 14:20:10

+0

两个有用的答案。两方面都学到了新东西。谢谢。 – 2014-08-30 14:21:44

回答

2

您可以用这种方式改变你的模式:

pattern <- paste0('^(',paste(keep, collapse = "|"),')$') # "^(A|AA|B)$" 

^意味着“字符串的开始“$“字符串末尾”

无论如何,你可以子集的data.frame更轻松地使用%in%操作:

mydata.subset <- mydata[colnames(mydata) %in% keep] 

或者也可以简单(如果你不感兴趣,在保持原始列顺序):

mydata.subset <- mydata[keep] 
0

一种方法是:

indx <- grep(paste(paste0("\\b", keep, "\\b"),collapse="|"), colnames(mydata), value=TRUE) 
    indx 
    #[1] "A" "AA" "B" 
mydata[indx] 
# A AA B 
#1 1 1 1 
#2 1 1 1 
#3 1 1 1