2012-06-23 7 views
5

Me he atascado en un problema menor y no he encontrado los términos de búsqueda adecuados para él. Tengo letras de "A" a "N" y quiero reemplazarlas por "G" con "A" - "G" según su posición en el alfabeto. usando gsub para eso parece engorroso. ¿O hay alguna expresión regular que pueda hacerlo de manera más inteligente?letras sustitutas con el conjunto correspondiente de letras

k <- rep(LETTERS[1:14],2) 
gsub(pattern="H", replace="A", x=k) 
gsub(pattern="I", replace="B", x=k) 
gsub(pattern="J", replace="C", x=k) 
gsub(pattern="K", replace="D", x=k) 
# etc. 

¿No hay alguna manera de que pueda convertir los caracteres a un entero y luego simplemente calculan dentro de los valores enteros y luego echando hacia atrás? ¿O hay alguna inversa de LETRAS? as.numeric() y as.integer() devuelve NA.

+0

Como usted tiene probablemente deducido de las respuestas sugeridas, 'match' es el' as.numeric' que estás buscando: 'match (c (" A "," S "," K "), LETRAS)' return {1, 19, 11}. – A5C1D2H2I1M1N2O1R2T1

+0

Sí, gracias. match() Necesito recordar. Tantas cosas nuevas y casi siempre me olvido de algo que encontré antes. Aunque el partido es bastante nuevo para mí. – Sebastian

Respuesta

11

Esto se traduce HN a AG:

chartr("HIJKLMN", "ABCDEFG", k) 
+0

Agradable. Es difícil superar eso en este caso, diría yo. –

+0

Una vez más, puse a leer la lista de funciones en 'base' en mi lista de tareas pendientes. Gracias por señalar esto. – Aaron

+0

Uh, me encontré con esa función cuando estaba buscando una función de reemplazo adecuada. Sin embargo, no lo intenté porque estaba asumiendo que el antiguo un nuevo parámetro solo era aplicable dentro de una cadena, no para vectores. Debería haberlo intentado. Por cierto, ¿alguien una idea de lo que representa Chartr? Es más fácil recordarlo. – Sebastian

3

Estoy seguro de que hay una manera de hacer esto más compacta, pero esto es probablemente el tipo de cosas que estaban pensando en su segunda idea, no expresiones regulares:

k <- factor(k) 
> k1 <- as.integer(k) %% 7 
> k1[k1 == 0] <- 7 
> LETTERS[k1] 
[1] "A" "B" "C" "D" "E" "F" "G" "A" "B" "C" "D" "E" "F" "G" "A" "B" "C" "D" "E" "F" "G" "A" 
[23] "B" "C" "D" "E" "F" "G" 

Probablemente hay una forma inteligente para eludir el problema del índice 0, pero no me siento terriblemente listo en este momento.

Editar

buenas sugerencias de los comentarios. En primer lugar, para manejar el 0 formulario de la aritmética modular:

k1 <- ((as.integer(k)-1) %%7) + 1 

y combinado con match se convierte en una sola línea:

k1 <- LETTERS[((match(k, LETTERS)-1) %% 7) + 1] 
+0

Aquí, puedes tomar prestada alguna astucia, y devolverla más tarde;) 'k1 <- ((como.integer (k) -1) %% 7) + 1' –

+1

@ JoshO'Brien, me gusta la astucia. Lo hace para que esto pueda resolverse en una línea: 'k1 = LETRAS [((coincidencia (k, LETRAS) -1) %% 7) + 1]'. – A5C1D2H2I1M1N2O1R2T1

4

Mi primer pensamiento cada vez que veo este tipo de problemas es match:

AG <- LETTERS[1:7] 
HN <- LETTERS[8:14] 

k <- rep(LETTERS[1:14],2) 
n <- AG[match(k, HN)] 
ifelse(is.na(n), k, n) 
# [1] "A" "B" "C" "D" "E" "F" "G" "A" "B" "C" "D" "E" "F" "G" "A" "B" "C" "D" "E" 
#[20] "F" "G" "A" "B" "C" "D" "E" "F" "G" 

me construyo una función inversa LETTERS la misma manera:

invLETTERS <- function(x) match(x, LETTERS[1:26]) 
invLETTERS(k) 
# [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 1 2 3 4 5 6 7 8 9 10 11 
#[26] 12 13 14 
4

Aquí es una solución limpia y directa:

k <- rep(LETTERS[1:14],2) 

# (1) Create a lookup vector whose elements can be indexed into 
#  by their names and will return their associated values 
subs <- setNames(rep(LETTERS[1:7], 2), LETTERS[1:14]) 
subs 
# A B C D E F G H I J K L M N 
# "A" "B" "C" "D" "E" "F" "G" "A" "B" "C" "D" "E" "F" "G" 

# (2) Use it. 
unname(subs[k]) 
# [1] "A" "B" "C" "D" "E" "F" "G" "A" "B" "C" "D" "E" "F" "G" 
# [15] "A" "B" "C" "D" "E" "F" "G" "A" "B" "C" "D" "E" "F" "G" 
2

Si su problema es sólo con un:

set.seed(1) 
k = sample(LETTERS[1:14], 42, replace=TRUE) 
temp = match(k, LETTERS) 
# > table(k) 
# k 
# A B C D E F G I J K L M N 
# 2 2 5 2 1 6 3 3 5 4 3 3 3 
k[which(temp > 7)] = LETTERS[temp[temp > 7] -7] 
# > table(k) 
# k 
# A B C D E F G 
# 2 5 10 6 4 9 6 
Cuestiones relacionadas