2012-03-01 11 views
21

Je suis en train de sélectionner des lignes dans une trame de données où la chaîne contenue dans une colonne correspond soit à une expression régulière ou une sous-chaîne:En utilisant regexp pour sélectionner les lignes dans R dataframe

dataframe:

aName bName pName call alleles logRatio strength 
AX-11086564 F08_ADN103 2011-02-10_R10 AB CG 0.363371 10.184215 
AX-11086564 A01_CD1919 2011-02-24_R11 BB GG -1.352707 9.54909 
AX-11086564 B05_CD2920 2011-01-27_R6 AB CG -0.183802 9.766334 
AX-11086564 D04_CD5950 2011-02-09_R9 AB CG 0.162586 10.165051 
AX-11086564 D07_CD6025 2011-02-10_R10 AB CG -0.397097 9.940238 
AX-11086564 B05_CD3630 2011-02-02_R7 AA CC 2.349906 9.153076 
AX-11086564 D04_ADN103 2011-02-10_R2 BB GG -1.898088 9.872966 
AX-11086564 A01_CD2588 2011-01-27_R5 BB GG -1.208094 9.239801 

Par exemple, je souhaite une structure de données contenant uniquement des lignes contenant ADN dans la colonne bName. Secondairement, je voudrais toutes les lignes qui contiennent ADN dans la colonne bName et qui correspondent 2011-02-10_R2 dans la colonne pName.

J'ai essayé d'utiliser les fonctions grep(), agrep() et plus, mais sans succès ...

Répondre

25
subset(dat, grepl("ADN", bName) & pName == "2011-02-10_R2") 

Note "&" (et non "& &" qui ne vectorisé) et que "==" (et non "=" qui est l'affectation).

Notez que vous auriez pu utiliser:

dat[ with(dat, grepl("ADN", bName) & pName == "2011-02-10_R2") , ] 

... et peut-être préférable lorsqu'il est utilisé dans les fonctions, cependant, qui renvoient des valeurs NA pour toutes les lignes où dat $ pName est NA. Ce défaut (que certains considèrent comme une caractéristique) pourrait être supprimé en ajoutant & !is.na(dat$pName) à l'expression logique.

-2

Pourquoi ne pas simplement:

grep 'ADN'|grep '2011-02-10_R2' 

Vous pouvez aussi le faire:

grep -P '\t.{4}(ADN).*(2011-02-10_R2).*' 
+8

Parce que la langue est [tag: R] – Andrie

+1

Désolé, n'a pas remarqué le 'r'. Je suppose que vous pouvez juste copier mon expression rationnelle puis –

8

Ici, vous allez .

Première recréez vos données:

dat <- read.table(text=" 
aName bName pName call alleles logRatio strength 
AX-11086564 F08_ADN103 2011-02-10_R10 AB CG 0.363371 10.184215 
AX-11086564 A01_CD1919 2011-02-24_R11 BB GG -1.352707 9.54909 
AX-11086564 B05_CD2920 2011-01-27_R6 AB CG -0.183802 9.766334 
AX-11086564 D04_CD5950 2011-02-09_R9 AB CG 0.162586 10.165051 
AX-11086564 D07_CD6025 2011-02-10_R10 AB CG -0.397097 9.940238 
AX-11086564 B05_CD3630 2011-02-02_R7 AA CC 2.349906 9.153076 
AX-11086564 D04_ADN103 2011-02-10_R2 BB GG -1.898088 9.872966 
AX-11086564 A01_CD2588 2011-01-27_R5 BB GG -1.208094 9.239801 
", header=TRUE) 

Ensuite, utilisez grepl pour construire un index logique des matches:

index1 <- with(dat, grepl("ADN", bName)) 
index2 <- with(dat, grepl("2011-02-10_R2", pName)) 

sous-ensemble maintenant en utilisant l'opérateur &:

dat[index1 & index2, ] 
     aName  bName   pName call alleles logRatio strength 
7 AX-11086564 D04_ADN103 2011-02-10_R2 BB  GG -1.898088 9.872966 
2

Corrigée selon les conseils d'Andrie. J'espère que cela devrait fonctionner. :)

df[grepl("ADN", df$bName),] 
df[grepl("ADN", df$bName) & df$pName == "2011-02-10_R2",] 
+0

Ces deux instructions renvoie une trame de données vide, pas les lignes souhaitées 1 et 7. – Andrie

+0

Oui, en effet, vous avez raison. J'ai besoin d'une pause. :) – DrDom

0

J'ai testé en utilisant Expresso et utilisé des regex de style .Net; vous devrez peut-être modifier pour votre saveur regex. J'ai également laissé des espaces blancs pour la lisibilité; supprime ou utilise un indicateur d'option regex à ignorer.

Le regex de base pour capturer toutes les lignes est:

(?<aName> [\w-]+) \s+ (?<bName> [\w_]+) \s+ (?<pName> [\w-_]+) \s+ (?<call> \w+) \s+ (?<alleles> \w+) \s+ (?<logRatio> [\d\.-]+) \s+ (?<strength> [\d\.-]+) 

De là, vous avez juste besoin de modifier l'expression régulière pour le groupe approprié de capture du nom (s) pour extraire uniquement les lignes que vous voulez.La version modifiée pour capturer à l'aide des critères que vous avez données (bname contient « ADN » et pName = « 2011-02-10_R2 ») est:

(?<aName> [\w-]+) \s+ (?<bName> [\w_]*ADN[\w_]*) \s+ (?<pName> 2011-02-10_R2) \s+ (?<call> \w+) \s+ (?<alleles> \w+) \s+ (?<logRatio> [\d\.-]+) \s+ (?<strength> [\d\.-]+) 
0

C'est une solution assez minime en utilisant dplyr et magrittr qui je pense est ce que vous êtes après:

Data: 
library(magrittr) 
library(stringr) 
dat <- read.table(text=" 
aName bName pName call alleles logRatio strength 
        AX-11086564 F08_ADN103 2011-02-10_R10 AB CG 0.363371 10.184215 
        AX-11086564 A01_CD1919 2011-02-24_R11 BB GG -1.352707 9.54909 
        AX-11086564 B05_CD2920 2011-01-27_R6 AB CG -0.183802 9.766334 
        AX-11086564 D04_CD5950 2011-02-09_R9 AB CG 0.162586 10.165051 
        AX-11086564 D07_CD6025 2011-02-10_R10 AB CG -0.397097 9.940238 
        AX-11086564 B05_CD3630 2011-02-02_R7 AA CC 2.349906 9.153076 
        AX-11086564 D04_ADN103 2011-02-10_R2 BB GG -1.898088 9.872966 
        AX-11086564 A01_CD2588 2011-01-27_R5 BB GG -1.208094 9.239801 
        ", header=TRUE) 

lignes qui contiennent l'ADN dans la colonne bname.

dat %>% 
    filter(str_detect(bName, "ADN") == TRUE) 

Secondairement, je voudrais toutes les lignes qui contiennent l'ADN dans la colonne bname et qui correspondent 2011-02-10_R2 dans la colonne pName.

dat %>% 
    filter(str_detect(bName, "ADN") & pName == "2011-02-10_R2") 
Questions connexes