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

4

5 回答 5

11

这将 HN 转换为 AG:

chartr("HIJKLMN", "ABCDEFG", k)
于 2012-06-23T20:00:19.583 回答
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
于 2012-06-23T19:00:37.157 回答
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"
于 2012-06-23T19:02:32.047 回答
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]
于 2012-06-23T18:46:59.800 回答
2

如果您的问题仅与 AN 有关:

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
于 2012-06-23T19:06:13.243 回答