web-dev-qa-db-fra.com

Utilisation de l'expression rationnelle pour sélectionner des lignes dans la trame de données R

J'essaie de sélectionner des lignes dans un cadre de données où la chaîne contenue dans une colonne correspond à une expression régulière ou à une sous-chaîne:

trame de données:

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 veux une trame de données contenant uniquement des lignes contenant ADN dans la colonne bName. Secondairement, je voudrais que 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 ...

24
Eric C.
subset(dat, grepl("ADN", bName)  &  pName == "2011-02-10_R2" )

Notez "&" (et non "&&" qui n'est pas vectorisé) et que "==" (et non "=" qui est affectation).

Notez que vous auriez pu utiliser:

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

... et cela pourrait être préférable lorsqu'il est utilisé dans des fonctions, cependant, cela retournera 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é par l'ajout de & !is.na(dat$pName) à l'expression logique.

33
42-

Voici.

Recréez d'abord 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 de correspondances:

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

Maintenant sous-ensemble en utilisant le & 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
8
Andrie

Corrigé 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",]
3
DrDom

J'ai testé en utilisant Expresso et utilisé des expressions régulières de style .Net; vous devrez peut-être Tweak pour votre saveur regex. J'ai également laissé des espaces pour la lisibilité; supprimer ou utiliser un indicateur d'option regex pour 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\.-]+ ) 

À partir de là, il vous suffit d'ajuster l'expression régulière pour les groupes de capture nommés appropriés pour extraire uniquement les lignes que vous souhaitez. La version modifiée à capturer en utilisant les critères que vous avez donnés (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
Darryl

Ceci est une solution assez minimale utilisant dplyr et magrittr qui, je pense, est ce que vous recherchez:

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 contenant ADN dans la colonne bName.

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

Secondairement, je voudrais que toutes les lignes qui contiennent 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") 
0
petergensler