2012-06-22 118 views
9

Me gustaría implementar una función con R que elimine caracteres repetidos en una cadena. Por ejemplo, digamos que mi función es nombrado removeRS, por lo que se supone que funciona de esta manera:¿Cómo puedo eliminar caracteres repetidos en una cadena con R?

removeRS('Buenaaaaaaaaa Suerrrrte') 
    Buena Suerte 
    removeRS('Hoy estoy tristeeeeeee') 
    Hoy estoy triste 

Mi función se va a utilizar con cuerdas escritas en español, por lo que no es tan común (o al menos correcta) para encontrar palabras que tienen más de tres vocales sucesivas. No molestarse por el posible sentimiento detrás de ellos. No obstante, hay palabras que pueden tener dos consonantes sucesivas (especialmente ll y rr), pero podríamos saltear esto de nuestra función.

Por lo tanto, para resumir, esta función debe reemplazar las letras que aparecen al menos tres veces seguidas con solo esa letra. En uno de los ejemplos anteriores, aaaaaaaaa se reemplaza por a.

¿Podría darme alguna pista para llevar a cabo esta tarea con R?

+0

"Esta tarea" no se ha especificado claramente. Las vocales repetidas que se arrastran pueden necesitar ser manejadas de forma diferente, pero esto no está claro a partir de la descripción. –

Respuesta

19

no pensé mucho cuidado en esto, pero esta es mi solución rápida utilizando referencias en las expresiones regulares :

gsub('([[:alpha:]])\\1+', '\\1', 'Buenaaaaaaaaa Suerrrrte') 
# [1] "Buena Suerte" 

() capta una carta primero, \\1 se refiere a esa carta, + significa para que coincida con una o más; junta todas estas piezas, podemos hacer coincidir una carta dos o más veces.

Para incluir otros caracteres además de los alfanuméricos, reemplace [[:alpha:]] con una expresión regular que coincida con lo que desee incluir.

+1

Gracias, ¿qué tal si quieres excluir algunas letras de esto? Por ejemplo, excluya las letras L y R. – Nestorghh

+0

'[: alpha:]' significa 'a-zA-Z'; si quieres ser específico, puedes decir, p. '[a-zA-KM-QS-Z]' para eliminar mayúsculas L y R; ver '? regexp' –

+0

Aquí hay una variación usando un estilo perl ancho cero lookahead regexp:' gsub ("([[: alpha:]]) (? = \\ 1)", "", s, perl = TRUE) '. Coincide con todos menos el último en cualquier ejecución de caracteres alfabéticos. –

5

Creo que debe prestar atención a las ambigüedades en la descripción de su problema. Este es un primer intento, pero está claro que no funciona con "buena suerte" en la forma que desee:

removeRS <- function(str) paste(rle(strsplit(str, "")[[1]])$values, collapse="") 
removeRS('Buenaaaaaaaaa Suerrrrte') 
#[1] "Buena Suerte" 
+0

Gracias por su respuesta @DWin. El ejemplo con "Buena suerte" no me molesta en absoluto y acepto y me disculpo por las ambigüedades. Las cosas en inglés no funcionan como en español en este sentido. Intenté tu solución y funciona como deseo. Por cierto, he editado la pregunta para dejarla más clara. – Nestorghh

0

Desde desea reemplazar las letras que aparecen al menos 3 veces, aquí está mi solución:

gsub("([[:alpha:]])\\1{2,}", "\\1", "Buennaaaa Suerrrtee") 
#[1] "Buenna Suertee" 

Como se puede ver la 4 "a" se han reducido a sólo el 1 a, el 3 r tiene se ha reducido a 1 r, pero el 2 ny el 2 e no han sido cambiados. Como se ha sugerido que puede sustituir a la [[:alpha:]] por cualquier combinación de [a-zA-KM-Z] o similares, e incluso usar el operador "or" | dentro de los corchetes squre [y|Q] si desea que su código para afectar sólo repeticiones de Y y Q.

gsub("([a|e])\\1{2,}", "\\1", "Buennaaaa Suerrrtee") 
# [1] "Buenna Suerrrtee" 
# triple r are not affected and there are no triple e. 
Cuestiones relacionadas