R使用For循环创建数字列中的字符列

时间:2015-06-16 20:22:45

标签: r for-loop mapping character lookup

我正在尝试根据现有的数字列创建一列字符,最好不使用for循环。我已经提出了各种各样的方法来做到这一点,但我一直觉得我做的比这要复杂得多。

以下是可怕且耗时的for循环版(已编辑)

joe <- as.data.frame(matrix(round(runif(10,1,5),0),nrow=10,ncol=1))
chr <- function(n) { rawToChar(as.raw(n)) }
m = ncol(joe)+1
for (i in 1:nrow(joe)){
  joe[i,m] <- chr(joe[i,m-1]+64)
}
joe

    V1 V2
1   2  B
2   1  A
3   3  C
4   2  B
5   1  A
6   3  C
7   2  B
8   5  E
9   3  C
10  4  D

呀。这样可行。正如所料。但是对于真实的数据集,该操作将花费很长时间。

如何使用像rawToChar这样的ASCII转换函数?

joe <- as.data.frame(matrix(round(runif(10,1,5),0),nrow=10,ncol=1))
joe[,ncol(joe)+1] <- rawToChar(as.raw(64+joe[,1]))
joe

    V1        V2
1   1 ACCAACACDC
2   3 ACCAACACDC
3   3 ACCAACACDC
4   1 ACCAACACDC
5   1 ACCAACACDC
6   3 ACCAACACDC
7   1 ACCAACACDC
8   3 ACCAACACDC
9   4 ACCAACACDC
10  3 ACCAACACDC

这完全不起作用。 rawToChar的输出不是矢量,而是字符串。有没有什么需要矢量数字输入并输出字符列表?

稍微放弃了这种方法,我能够获得另外两种工作方式......但它们并不是特别优雅,需要花费相当多的代码才能实现。首先是查找表方法:

library("dplyr")
grades <- as.data.frame(matrix(seq(1,5,by=1),nrow=5,ncol=1))
grades <- cbind(grades, c("A","B","C","D","E"))
colnames(grades) <- c("num","ltr")
joe <- as.data.frame(matrix(round(runif(10,1,5),0)),nrow=10,ncol=1)
colnames(joe) <- c("num")
left_join(joe, grades, by="num")

    num ltr
1    3   C
2    4   D
3    2   B
4    5   E
5    4   D
6    2   B
7    2   B
8    1   A
9    5   E
10   2   B

现在使用因素和水平:

joe <- as.data.frame(matrix(round(runif(10,1,5),0)),nrow=10,ncol=1)
joe$V2 <- as.factor(joe$V1)
levels(joe$V2) <- c("A","B","C","D","E")
joe$V2 <- as.character(joe$V2)
joe

   V1 V2
1   4  D
2   1  A
3   3  C
4   2  B
5   3  C
6   3  C
7   5  E
8   2  B
9   4  D
10  4  D

所以我的问题是......是否还有其他更简单,更优雅的方法,我还没有想到呢?因为我确实发明了一些非常复杂的方法来做一个非常简单的操作。

提前感谢您的意见。

1 个答案:

答案 0 :(得分:1)

我不确定你要做什么,但只是看看你的最后一个例子,看起来你正试图做这样的事情:

set.seed(123) # good practice for reproducible answer
joe <- data.frame( V1 = sample.int(5,10,replace=TRUE) ) # simpler way
joe$V2 <- LETTERS[joe$V1]
joe
#    V1 V2
# 1   2  B
# 2   4  D
# 3   3  C
# 4   5  E
# 5   5  E
# 6   1  A
# 7   3  C
# 8   5  E
# 9   3  C
# 10  3  C