2012-06-23 14 views
5

Utknąłem na niewielkim problemie i nie znalazłem odpowiednich wyszukiwanych terminów. Mam litery od "A" - "N" i chcę zastąpić te większe od "G" literami "A" - "G" zgodnie z ich pozycją w alfabecie. przy użyciu gsub, ponieważ wydaje się to uciążliwe. Czy istnieje regex, który może zrobić to mądrzej?Litery zastępcze z odpowiednim zestawem liter

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. 

tam nie jest jakiś sposób mogę przekonwertować te znaki do liczby całkowitej, a następnie po prostu obliczyć ciągu liczb całkowitych, a potem rzucając z powrotem? Czy istnieje jakaś odwrotność LISTÓW? as.numeric() i as.integer() zwraca NA.

+0

Jak już zapewne wywnioskował z sugerowanych odpowiedzi, 'match' jest szukanym' as.numeric' 'match (c (" A "," S "," K "), LISTY) return {1, 19, 11}. – A5C1D2H2I1M1N2O1R2T1

+0

Tak, dziękuję. match() Muszę pamiętać. Tyle nowych rzeczy i prawie zawsze zapominam o czymś, co spotkałem wcześniej. Chociaż mecz jest dla mnie całkiem nowy. – Sebastian

Odpowiedz

11

To przekłada HN do AG:

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

Nice. Trudno to pokonać w tym przypadku, powiedziałbym. –

+0

Jeszcze raz, umieszczam czytanie listy funkcji w 'bazie' na liście do zrobienia. Dziękuję za wskazanie tego. – Aaron

+0

Uh, natknąłem się na tę funkcję, gdy szukałem odpowiedniej funkcji zastępowania. Jednak nie próbowałem tego, ponieważ zakładałem, że nowy parametr ma zastosowanie tylko w jednym ciągu znaków, a nie wektory. Powinienem był tego spróbować. BTW ktoś pomysł, co oznacza chartr? Łatwiej go zapamiętać. – Sebastian

3

Jestem pewien, że istnieje sposób, aby to bardziej zwarta, ale jest to prawdopodobnie coś takiego można było myśleć o w drugim, nie regex pomysł:

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" 

Jest prawdopodobnie sprytny sposób omijać kwestię indeksu 0, ale w tej chwili nie czuję się strasznie sprytnie.

Edytuj

dobre propozycje z komentarzy. Po pierwsze, aby obsłużyć 0 format modułowe arytmetyczne:

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

i połączono z match zamienia się w jedną wkładką:

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

Tutaj możesz pożyczyć trochę sprytu i spłacić później;) 'k1 <- ((as.integer (k) -1) %% 7) + 1' –

+1

@ JoshO'Brien, podoba mi się spryt. To sprawia, że ​​można to rozwiązać w jednym wierszu: 'k1 = LISTY [((mecz (k, LISTY) -1) %% 7) + 1]'. – A5C1D2H2I1M1N2O1R2T1

4

Moja pierwsza myśl, gdy widzę problemów, jak to jest 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" 

bym skonstruować funkcję odwrotną LETTERS ten sam sposób:

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

Oto czyste i proste rozwiązanie:

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

Jeśli problem jest tylko za pomocą:

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 
Powiązane problemy