我有一个数据框。我要实现的是用2个字符(长度为2的字符串)而不是整数编码的列(代表月份)。
以下是一些数据样本:
wifi <- data.frame(replicate(2,8:12))
哪个创建这样的数据框:
X1 X2
1 8 8
2 9 9
3 10 10
4 11 11
5 12 12
我想要这样的东西:
X1 X2
1 8 08
2 9 09
3 10 10
4 11 11
5 12 12
这是我做的功能:
A <- function(x) {
if(nchar(x)==1) {
return(paste0("0",x))
} else {
return(x)
}
}
这似乎可以正常工作(A(“ 9”)==“ 09”和A(“ 12”)==“ 12”)。
我尝试过
cbind(wifi[1], lapply(wifi[2], A) )
这是我得到的结果,似乎此函数一次应用于所有元素,而不是应用于每个元素。
X1 X2
1 8 08
2 9 09
3 10 010
4 11 011
5 12 012
警告信息: 如果if(nchar(x)== 1){: 条件的长度> 1,并且只会使用第一个元素
有人知道我可以解决这个问题吗?
答案 0 :(得分:2)
您应该改用sprintf函数。
这会将其应用于所有列:
sapply(wifi, function(x) sprintf("%02.0f", x))
仅适用于第二个:
sprintf("%02.0f", wifi$X2)
sprintf
是一个内置函数,用于格式化字符串(与C语言相同),并且完全可以执行您希望A
函数所要做的
最好将sapply
用于数据帧。
答案 1 :(得分:1)
我会使用sprintf()
A <- function(x) {
sprintf("%02d", x)
}
wifi[[2]] <- A(wifi[[2]])
wifi
X1 X2
1 8 08
2 9 09
3 10 10
4 11 11
5 12 12
但是当前功能有什么问题?
几乎没有。
if () {} else {}
处理长度为1的元素,而lapply(wifi[2], A)
将其馈入整个向量。因此,您可以使用different subsetting使用原始功能执行此操作:
sapply(wifi[[2]], A)
但是,最好使用向量化的ifelse()
并放下*apply()
:
A <- function(x) {
x <- as.character(x)
ifelse(nchar(x) == 1, paste0("0", x), x)
}