web-dev-qa-db-fra.com

Correspondance de motif à l'aide d'un caractère générique

Comment identifier une chaîne à l'aide d'un caractère générique?

J'ai trouvé glob2rx, mais je ne comprends pas très bien comment l'utiliser. J'ai essayé d'utiliser le code suivant pour sélectionner les lignes du bloc de données qui commencent par le mot blue:

# make data frame
a <- data.frame( x =  c('red','blue1','blue2', 'red2'))

# 1
result <- subset(a, x == glob2rx("blue*") )

# 2
test = ls(pattern = glob2rx("blue*"))
result2 <- subset(a, x == test )

# 3
result3 <- subset(a, x == pattern("blue*") )

Cependant, ni l'un ni l'autre n'a fonctionné. Je ne sais pas si je devrais utiliser une fonction différente pour essayer de le faire.

37
djq

Si vous souhaitez examiner des éléments à l'intérieur d'une trame de données, vous ne devez pas utiliser ls() qui ne regarde que les noms des objets dans l'espace de travail actuel (ou s'il est utilisé à l'intérieur d'une fonction dans l'environnement actuel). Les noms de domaine ou les éléments à l'intérieur de ces objets ne sont pas visibles par ls() (à moins bien sûr que vous ajoutiez un argument d'environnement à l'appel ls(.)-). Essayez d'utiliser grep() qui est la fonction cheval de bataille pour la correspondance de motifs des vecteurs de caractères:

result <- a[ grep("blue", a$x) , ]  # Note need to use `a$` to get at the `x`

Si vous souhaitez utiliser un sous-ensemble, considérez la fonction étroitement liée grepl() qui renvoie un vecteur de logiques pouvant être utilisé dans l'argument du sous-ensemble:

subset(a, grepl("blue", a$x))
      x
2 blue1
3 blue2

Edit: Ajout d'une utilisation "correcte" de glob2rx dans le sous-ensemble ():

result <- subset(a,  grepl(glob2rx("blue*") , x) )
result
      x
2 blue1
3 blue2

Je ne pense pas avoir réellement compris glob2rx Avant de revenir à cette question. (J'ai bien compris les problèmes de portée qui étaient à l'origine des difficultés de l'interrogateur. Quiconque lit ceci devrait maintenant faire défiler jusqu'à la réponse de Gavin et la voter.)

41
42-

glob2rx() convertit un modèle comprenant un caractère générique en l'expression régulière équivalente. Vous devez ensuite transmettre cette expression régulière à l'un des outils de mise en correspondance de motifs de R.

Si vous voulez faire correspondre "blue*"* A le caractère générique habituel, pas l'expression régulière, ce qui signifie que nous utilisons glob2rx() pour convertir le motif générique en une expression régulière utile:

> glob2rx("blue*")
[1] "^blue"

L'objet retourné est une expression régulière.

Compte tenu de vos données:

x <- c('red','blue1','blue2', 'red2')

nous pouvons faire correspondre les motifs en utilisant grep() ou des outils similaires:

> grx <- glob2rx("blue*")
> grep(grx, x)
[1] 2 3
> grep(grx, x, value = TRUE)
[1] "blue1" "blue2"
> grepl(grx, x)
[1] FALSE  TRUE  TRUE FALSE

Quant au problème de sélection des lignes que vous avez publié

> a <- data.frame(x =  c('red','blue1','blue2', 'red2'))
> with(a, a[grepl(grx, x), ])
[1] blue1 blue2
Levels: blue1 blue2 red red2
> with(a, a[grep(grx, x), ])
[1] blue1 blue2
Levels: blue1 blue2 red red2

ou via subset():

> with(a, subset(a, subset = grepl(grx, x)))
      x
2 blue1
3 blue2

J'espère que cela explique ce que fait grob2rx() et comment l'utiliser?

32
Gavin Simpson

Vous êtes sur la bonne voie - le mot-clé que vous devriez rechercher sur Google est Expressions régulières. R les prend en charge d'une manière plus directe que cela en utilisant grep() et quelques autres alternatives.

Voici une discussion détaillée: http://www.regular-expressions.info/rlanguage.html

4
Brian MacKay

Vous pouvez également utiliser le package data.table et sa fonction Like, détails ci-dessous Comment sélectionner les lignes R data.table en fonction de la correspondance de sous-chaîne (comme la SQL)

2
usct01

Si vous voulez vraiment utiliser des caractères génériques pour identifier des variables spécifiques, vous pouvez utiliser une combinaison de ls() et grep() comme suit:

l = ls()
vars.with.result <- l[grep("result", l)]

2
Brian D