2012-06-23 63 views
5

我遇到了一個小問題,我沒有找到正確的搜索條件。 我有來自「A」 - 「N」的字母,並且希望根據它們在字母表中的位置將這些大於「G」的字母替換爲「A」 - 「G」。使用gsub這似乎很麻煩。或者有沒有任何正則表達式可以做到更智能?替代字母和相應的字母集合

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. 

是不是有一些方法,我可以轉換的字符爲整數,然後簡單地將整數值內計算出事後鑄造回來?或者是否有任何信件的反面? as.numeric()as.integer()返回NA

+0

正如你可能從推薦的答案中得出結論,'match'是你要找的'as.numeric':'match(c(「A」,「S」,「K」),LETTERS)'會返回{1,19,11}。 – A5C1D2H2I1M1N2O1R2T1

+0

是的,謝謝。 match()我需要記住。這麼多新東西,我幾乎總是忘記了我之前遇到的東西。儘管比賽對我來說很新穎。 – Sebastian

回答

11

這意味着HN到AG:

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

不錯。在這種情況下,很難打敗,我會說。 –

+0

再一次,我在「我的待辦事項」清單中閱讀了「base」中的函數列表。感謝您指出這一點。 – Aaron

+0

呃,我在尋找適當的替換函數時遇到了這個函數。然而,我沒有嘗試,因爲我假設舊的一個新的參數只適用於一個字符串不適用於向量。我應該嘗試過。順便說一句,任何人都知道chartr代表什麼?它更容易記住它。 – Sebastian

3

我敢肯定有一種方法,使這種更緊湊,但是這可能是那種你在你的第二個,非正則表達式的想法正在考慮的事情:

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" 

有可能是一個聰明的辦法以迴避0指數問題,但目前我並不感到非常聰明。

編輯

好從的意見建議。首先,處理0形式模算術:

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

,並結合match它變成一個班輪:

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

在這裏,你可以借用一些聰明的東西,並在以後付清;)k1 < - ((as.integer(k)-1)%% 7)+ 1' –

+1

@ JoshO'Brien,我喜歡聰明。它使得它可以在一行中解決:'k1 = LETTERS [((match(k,LETTERS)-1)%% 7)+ 1]'。 – A5C1D2H2I1M1N2O1R2T1

4

我首先想到的,每當我看到這樣的問題是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" 

我構建逆LETTERS功能以同樣的方式:

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

這裏有一個乾淨和簡單的解決方案:

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

如果你的問題是隻能用:

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