Reemplace los caracteres que no son ascii con una lista de cadenas definida sin un bucle en R

Quiero reemplazar los caracteres que no son ascii (por ahora solo en español), por su equivalente ascii. Si tengo "á", quiero reemplazarlo con "a" y así sucesivamente.

Creé esta función (funciona bien), pero no quiero usar un bucle (incluidos los bucles internos como sapply).

latin2ascii<-function(x) {
if(!is.character(x)) stop ("input must be a character object")
require(stringr)
mapL<-c("á","é","í","ó","ú","Á","É","Í","Ó","Ú","ñ","Ñ","ü","Ü")
mapA<-c("a","e","i","o","u","A","E","I","O","U","n","N","u","U")
for(y in 1:length(mapL)) {
  x<-str_replace_all(x,mapL[y],mapA[y])
  }
x
}

¿Hay una forma elegante de solucionarlo? Se agradece cualquier ayuda, sugerencia o modificación.

preguntado el 22 de mayo de 12 a las 16:05

2 Respuestas

gsubfn() en el paquete del mismo nombre es muy bueno para este tipo de cosas:

library(gsubfn)

# Create a named list, in which:
#   - the names are the strings to be looked up
#   - the values are the replacement strings
mapL <- c("á","é","í","ó","ú","Á","É","Í","Ó","Ú","ñ","Ñ","ü","Ü")
mapA <- c("a","e","i","o","u","A","E","I","O","U","n","N","u","U")

# ll <- setNames(as.list(mapA), mapL) # An alternative to the 2 lines below
ll <- as.list(mapA)
names(ll) <- mapL


# Try it out
string <- "ÍÓáÚ"
gsubfn("[áéíóúÁÉÍÓÚñÑüÜ]", ll, string)
# [1] "IOaU"

Edit:

G. Grothendieck señala que la base R también tiene una función para esto:

A <- paste(mapA, collapse="")
L <- paste(mapL, collapse="")
chartr(L, A, "ÍÓáÚ")
# [1] "IOaU"

contestado el 23 de mayo de 12 a las 00:05

Thanks! works perfectly. Only one question (just to know); do you know if the gsubfn function use any kind of internal loop? Should be faster than sapply? - Álvaro

@Álvaro -- No creo gsubfn() is particularly fast -- 'just' convenient and elegant. - Josh O'Brien

Ver también chartr en la base de R, que parece estar bien para el problema tal como se indica, aunque si hay variaciones en el problema real, como reemplazar dos secuencias de caracteres, entonces gsubfn could still handle it but not chartr. - G. Grothendieck

@G.Grothendieck: gracias por señalarlo. Lo he agregado a la respuesta. - Josh O'Brien

I like the version by Josh, but I thought I might add another 'vectorized' solution. It returns a vector of unaccented strings. It also only relies on the base funciones.

x=c('íÁuÚ','uíÚÁ')

mapL<-c("á","é","í","ó","ú","Á","É","Í","Ó","Ú","ñ","Ñ","ü","Ü")
mapA<-c("a","e","i","o","u","A","E","I","O","U","n","N","u","U")
split=strsplit(x,split='')
m=lapply(split,match,mapL)
mapply(function(split,m) paste(ifelse(is.na(m),split,mapA[m]),collapse='') , split, m)
# "iAuU" "uiUA"

contestado el 22 de mayo de 12 a las 17:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.