我有一组看起来像这样的数据:
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
为了感兴趣,如果我需要在动物ID之前添加两个或三个零,该怎么办?
8 回答
简短版本:使用formatC或sprintf .
版本较长:
有几种功能可用于格式化数字,包括添加前导零 . 哪一个最好取决于您想要做的其他格式 .
问题的例子很简单,因为所有的值都有相同的数字位数,所以让我们尝试一个更难的例子来制作10宽度8的幂 .
paste (它的变体
paste0
)通常是您遇到的第一个字符串操作函数 . 它们并非真正用于操纵数字,但它们可用于此 . 在我们总是必须预先设置一个零的简单情况下,paste0
是最佳解决方案 .对于数字中存在可变位数的情况,您必须手动计算要预先设置的零数,这非常可怕,您应该只是出于病态的好奇心 .
来自
stringr
的 str_pad 与paste
的工作方式类似,因此您更明确地想要填充内容 .同样,它并不是真正设计用于数字,所以更难的情况需要一点思考 . 我们应该只能说“用零填充宽度为8”,但看看这个输出:
您需要设置科学惩罚option,以便始终使用固定符号(而不是科学符号)格式化数字 .
stringi
中的 stri_pad 与stringr
中的str_pad
完全相同 .formatC 是C函数printf的接口 . 使用它需要一些基础功能的基础知识(参见链接) . 在这种情况下,重要的是
width
参数,format
为"integer""d"
,"0"
flag
为前置零 .这是我最喜欢的解决方案,因为它很容易修改宽度,并且功能足以进行其他格式更改 .
sprintf 是同名C函数的接口;像
formatC
但语法不同 .sprintf
的主要优点是您可以在较长的文本位中嵌入格式化的数字 .另见goodside's answer .
为了完整性,值得一提的是偶尔有用的其他格式化函数,但没有预先添加零的方法 .
format ,一种用于格式化任何类型对象的通用函数,带有数字方法 . 它的工作方式有点像
formatC
,但还有另一个界面 .prettyNum 是另一种格式化功能,主要用于创建手动轴刻度标签 . 它适用于各种数字 .
scales 包具有多种功能,例如percent,date_format和dollar,用于专业格式类型 .
对于无论
data$anim
中有多少位数都能正常工作的一般解决方案,请使用sprintf
函数 . 它的工作原理如下:在您的情况下,您可能想要:
data$anim <- sprintf("%06d", data$anim)
扩展@ goodside的回复:
在某些情况下,您可能希望用零填充字符串(例如fips代码或其他类似数字的因子) . 在OSX / Linux中:
但是因为
sprintf()
在Windows 7中调用操作系统的Csprintf()
命令,讨论了here,所以会得到不同的结果:所以在Windows机器上,解决方法是:
来自
stringr
包的str_pad
是另一种选择 .这是另一种方法,可以将字符串添加到0到字符串,例如CUSIPs,它有时看起来像一个数字,许多应用程序(如Excel)将损坏并删除前导0或将它们转换为科学记数法 .
当我尝试@metasequoia提供的答案时,返回的向量具有前导空格而不是
0
. 这与@ user1816679提到的问题相同 - 删除0
周围的引号或从%d
更改为%s
也没有任何区别 . 仅供参考,我正在使用在Ubuntu服务器上运行的RStudio Server . 这个小小的两步解决方案对我有用:gsub(pattern = " ", replacement = "0", x = sprintf(fmt = "%09s", ids[,CUSIP]))
使用
magrittr
包中的%>%
管道函数,它可能如下所示:sprintf(fmt = "%09s", ids[,CUSIP]) %>% gsub(pattern = " ", replacement = "0", x = .)
我更喜欢单功能解决方案,但它确实有效 .
这是一个可推广的基本R函数:
我喜欢
sprintf
但它带有以下警告:对于您希望数字字符串保持一致的其他情况,我创建了一个函数 .
有人可能会发现这一点有用:
抱歉格式化 .