2012-06-23 15 views
5

Mi sono bloccato su un problema minore e non ho trovato i termini di ricerca giusti per questo. Ho lettere da "A" - "N" e voglio sostituirle con una maggiore di "G" con "A" - "G" in base alla loro posizione nell'alfabeto. usando gsub per quello sembra ingombrante. O c'è qualche regex che può farlo in modo più intelligente?lettere sostitutive con il corrispondente set di lettere

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. 

Non c'è qualche modo per convertire i personaggi per intero e poi semplicemente calcolare entro i valori interi e poi gettando indietro? O c'è qualche inverso di LETTERE? as.numeric() e as.integer() restituisce NA.

+0

Come hai probabilmente capito dalle risposte suggerite, 'match' è il' as.numeric' che stai cercando: 'match (c (" A "," S "," K "), LETTERS)' return {1, 19, 11}. – A5C1D2H2I1M1N2O1R2T1

+0

Sì grazie. match() Ho bisogno di ricordare. Così tante cose nuove e quasi dimentico quasi sempre qualcosa che ho incontrato prima. Anche se la partita è abbastanza nuova per me. – Sebastian

risposta

11

Questo si traduce HN a AG:

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

Bello. Difficile da battere in questo caso, direi. –

+0

Ancora una volta, metto a leggere l'elenco delle funzioni in 'base' nella mia lista delle cose da fare. Grazie per aver segnalato questo. – Aaron

+0

Uh, mi sono imbattuto in quella funzione quando stavo cercando una funzione di sostituzione corretta. Comunque non l'ho provato perché stavo assumendo che il vecchio parametro fosse applicabile solo all'interno di una stringa e non per i vettori. Avrei dovuto provarlo Qualcuno sa un'idea di cosa significhi chartr? È più facile ricordarlo. – Sebastian

3

Sono sicuro che c'è un modo per rendere questo più compatto, ma questo è probabilmente il genere di cosa stavi pensando di nel vostro secondo, idea non regex:

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" 

C'è probabilmente un modo intelligente per eludere il problema con l'indice 0, ma al momento non mi sento particolarmente intelligente.

Modifica

Buoni suggerimenti dai commenti. In primo luogo, per gestire il modulo 0 aritmetica modulare:

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

e combinato con match si trasforma in una battuta:

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

Qui puoi prendere in prestito un po 'di intelligenza e ripagarlo più tardi;) 'k1 <- ((as.integer (k) -1) %% 7) + 1' –

+1

@ JoshO'Brien, mi piace l'intelligenza. Fa sì che questo possa essere risolto in una riga: 'k1 = LETTERS [((match (k, LETTERS) -1) %% 7) + 1]'. – A5C1D2H2I1M1N2O1R2T1

4

mio primo pensiero ogni volta che vedo problemi come questo è 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" 

mi piacerebbe costruire una funzione inversa LETTERS allo stesso modo:

01.235.164,106 mila
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

Ecco una soluzione pulita e lineare:

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

Se il problema è solo 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 
Problemi correlati