使用R添加前导零
我有一组数据,看起来像这样:
anim <- c(25499,25500,25501,25502,25503,25504) sex <- c(1,2,2,1,2,1) wt <- c(0.8,1.2,1.0,2.0,1.8,1.4) data <- data.frame(anim,sex,wt) data anim sex wt anim2 1 25499 1 0.8 2 2 25500 2 1.2 2 3 25501 2 1.0 2 4 25502 1 2.0 2 5 25503 2 1.8 2 6 25504 1 1.4 2
我想在每个动物ID之前添加一个零:
data anim sex wt anim2 1 025499 1 0.8 2 2 025500 2 1.2 2 3 025501 2 1.0 2 4 025502 1 2.0 2 5 025503 2 1.8 2 6 025504 1 1.4 2
为了感兴趣,如果我需要在动物身份证之前添加两到三个零呢?
短版本:使用formatC
或sprintf
。
较长的版本:
有几个函数可用于格式化数字,包括添加前导零。 哪一个最好取决于你想要做的其他格式。
从这个问题的例子是很容易的,因为所有的值都有相同的数字开始,所以让我们尝试一个更强的例子,使得10宽度8的权力。
anim <- 25499:25504 x <- 10 ^ (0:5)
paste
(和它的变体paste0
)通常是你遇到的第一个string操作函数。 它们并不是真正用于操纵数字的,但是可以用于这个目的。 在简单的情况下,我们总是需要预先设置一个零, paste0
是最好的解决scheme。
paste0("0", anim) ## [1] "025499" "025500" "025501" "025502" "025503" "025504"
对于数字中有可变数字位数的情况,您必须手动计算需要多less个零,这太可怕了,您应该只是出于病态的好奇。
来自stringr
工作原理类似于paste
,使得它更加明确,你想要的东西。
library(stringr) str_pad(anim, 6, pad = "0") ## [1] "025499" "025500" "025501" "025502" "025503" "025504"
再一次,它不是真正用于数字,所以更难的情况下需要一点思考。 我们应该可以说“填充零到宽度8”,但看看这个输出:
str_pad(x, 8, pad = "0") ## [1] "00000001" "00000010" "00000100" "00001000" "00010000" "0001e+05"
您需要设置科学惩罚选项,以便始终使用固定的符号(而不是科学符号)格式化数字。
library(withr) with_options( c(scipen = 999), str_pad(x, 8, pad = "0") ) ## [1] "00000001" "00000010" "00000100" "00001000" "00010000" "00100000"
stri_pad
中的stringi
与stri_pad
中的stringi
完全相同。
formatC
是C函数printf
的接口。 使用它需要一些关于这个潜在function的神秘的知识(见链接)。 在这种情况下,重要的要点是width
参数, format
为“整数”为"d"
”,以及用于预置零的"0"
flag
。
formatC(anim, width = 6, format = "d", flag = "0") ## [1] "025499" "025500" "025501" "025502" "025503" "025504" formatC(x, width = 8, format = "d", flag = "0") ## [1] "00000001" "00000010" "00000100" "00001000" "00010000" "00100000"
这是我最喜欢的解决scheme,因为修改宽度很容易,而且function足够强大,可以进行其他格式更改。
sprintf
是同名C函数的接口; 像formatC
但是使用不同的语法。
sprintf("%06d", anim) ## [1] "025499" "025500" "025501" "025502" "025503" "025504" sprintf("%08d", x) ## [1] "00000001" "00000010" "00000100" "00001000" "00010000" "00100000"
sprintf
的主要优点是可以将格式化的数字embedded到较长的文本位中。
sprintf( "Animal ID %06d was a %s.", anim, sample(c("lion", "tiger"), length(anim), replace = TRUE) ) ## [1] "Animal ID 025499 was a tiger." "Animal ID 025500 was a tiger." ## [3] "Animal ID 025501 was a lion." "Animal ID 025502 was a tiger." ## [5] "Animal ID 025503 was a tiger." "Animal ID 025504 was a lion."
另请参阅goodside的回答 。
为了完整起见,值得一提的是偶尔有用的其他格式化函数,但没有预先置零的方法。
format
,用于格式化任何types的对象的通用函数,用数字方法。 它有点像formatC
,但有另一个接口。
prettyNum
是另一种格式化函数,主要用于创build手动轴刻度标签。 它适用于广泛的数字。
对于专业的格式types, scales
包有几个function,如percent
,date格式和dollar
。
对于一个通用的解决scheme,无论data$anim
有多less个数字,都可以使用sprintf
函数。 它是这样工作的:
sprintf("%04d", 1) # [1] "0001" sprintf("%04d", 104) # [1] "0104" sprintf("%010d", 104) # [1] "0000000104"
在你的情况下,你可能想要: data$anim <- sprintf("%06d", data$anim)
扩大@ goodside的repsonse:
在某些情况下,你可能想填充一个零(例如代码或其他类似数字的因素)的string。 在OSX / Linux中:
> sprintf("%05s", "104") [1] "00104"
但是因为sprintf()
调用操作系统的C sprintf()
命令,在这里讨论,在Windows 7中,你会得到一个不同的结果:
> sprintf("%05s", "104") [1] " 104"
所以在Windows机器上的工作是:
> sprintf("%05d", as.numeric("104")) [1] "00104"
从stringr
包stringr
是一种替代scheme。
anim = 25499:25504 str_pad(anim, width=6, pad="0")
data$anim <- sapply(0, paste0,data$anim)
这是另外一种方法,可以将string0加到string上,比如CUSIP ,有时看起来像一个数字,Excel等许多应用程序将会破坏并删除前面的0或将它们转换为科学记数法。
当我试着@metasequoia提供的答案时,返回的向量具有前导空格而不是0
s。 这与@ user1816679提到的问题是一样的 – 删除0
周围的引号或从%d
改为%s
也没有什么不同。 仅供参考,我正在使用在Ubuntu服务器上运行的RStudio服务器。 这个小小的两步解决scheme为我工作:
gsub(pattern = " ", replacement = "0", x = sprintf(fmt = "%09s", ids[,CUSIP]))
使用magrittr
包中的%>%
pipe道函数,它可能看起来像这样:
sprintf(fmt = "%09s", ids[,CUSIP]) %>% gsub(pattern = " ", replacement = "0", x = .)
我更喜欢单function的解决scheme,但它的工作原理。
对于其他你希望数字string一致的情况,我做了一个函数。
有人可能会觉得这很有用:
idnamer<-function(x,y){#Alphabetical designation and number of integers required id<-c(1:y) for (i in 1:length(id)){ if(nchar(id[i])<2){ id[i]<-paste("0",id[i],sep="") } } id<-paste(x,id,sep="") return(id) } idnamer("EF",28)
对不起格式。