2014-08-30 56 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