我正在尝试根据现有的数字列创建一列字符,最好不使用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
所以我的问题是......是否还有其他更简单,更优雅的方法,我还没有想到呢?因为我确实发明了一些非常复杂的方法来做一个非常简单的操作。
提前感谢您的意见。
答案 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