2011-11-23 9 views
6

Tengo un vector compuesto de entradas tales como "ZZZ1Z01Z0ZZ0", "1001ZZ0Z00Z0", y así sucesivamente, y quiero subconjunto de este vector basado en condiciones tales como:Cómo subconjunto vector basado en el carácter de cadena?

  1. El tercer personaje es un Z
  2. el tercer y séptimo personajes son Z
  3. el tercer y séptimo personajes son Z, y ninguno de los otros personajes son Z

he intentado jugar con strsplit y grep, pero no pude encontrar una forma de restringir mis condiciones basadas en la posi ción del personaje en la cadena. ¿Alguna sugerencia?

¡Muchas gracias!

+1

¿Los vectores siempre tendrán la misma longitud y solo 0, 1s y Z? No sé cómo funciona esto, solo podría darle una expresión regular :) – sinni800

Respuesta

10

Puede hacerlo con expresiones regulares (consulte ?regexp para obtener detalles sobre expresiones regulares).

grep devuelve la ubicación de la coincidencia y devuelve un vector de longitud cero si no se encuentra ninguna coincidencia. Es posible que desee utilizar grepl en su lugar, ya que devuelve un vector lógico que puede utilizar para subconjunto.

z <- c("ZZZ1Z01Z0ZZ0", "1001ZZ0Z00Z0") 
# 3rd character is Z ("^" is start of string, "." is any character) 
grep("^..Z", z) 
# 3rd and 7th characters are Z 
grep("^..Z...Z", z) 
# 3rd and 7th characters are Z, no other characters are Z 
# "[]" defines a "character class" and "^" in a character class negates the match 
# "{n}" repeats the preceding match n times, "+" repeats is one or more times 
grep("^[^Z]{2}Z[^Z]{3}Z[^Z]+", z) 
+0

¿Y por qué siquiera considerarías hacerlo de otra manera? –

+0

Muchas gracias por su ayuda. ¡Empecé a jugar con expresiones regulares y son ** increíbles **! No puedo creer que no me haya topado con esto antes. ¡Gracias! –

2

Puede hacer las dos primeras sin expresiones regulares utilizando el comando substr para extraer caracteres específicos si lo desea.

# Grab the third character in each element and compare it to Z 
substr(z, 3, 3) == "Z" 
# Check if the 3rd and 7th characters are both Z 
(substr(z, 3, 3) == "Z") & (substr(z, 7, 7) == "Z") 

Sin embargo, el enfoque de expresión regular Joshua dio es más flexible y tratando de poner en práctica la tercera restricción que tenía uso de un enfoque substr sería un dolor. Las expresiones regulares son mucho más adecuadas para un problema como su tercera restricción y aprender cómo usarlas nunca es una mala idea.

3

Ampliando la respuesta de Josh, que desea

your_dataset <- data.frame(
    z = c("ZZZ1Z01Z0ZZ0", "1001ZZ0Z00Z0") 
) 
regexes <- c("^..Z", "^..Z...Z", "^[^Z]{2}Z[^Z]{3}Z[^Z]+") 

lapply(regexes, function(rx) 
{ 
    subset(your_dataset, grepl(rx, z)) 
}) 

Ten en cuenta también la sustitución de grepl(rx, z) con str_detect(z, rx), utilizando el paquete stringr. (No existe una diferencia real excepto por un código ligeramente más legible.)

+0

Mi voto reconoce la sugerencia del subconjunto (., Grepl (.)). –

Cuestiones relacionadas