R语言中为P开头的编号添加前导0以统一为4位数字格式的问题求助
R语言中为P开头的编号添加前导0以统一为4位数字格式的问题求助
我来帮你解决这个问题~你现在遇到的报错其实是因为没有按单个元素来处理补0的逻辑,咱们一步步拆解:
先说说你代码出错的原因
你写的rep(0,4-length(num))里,length(num)返回的是整个num列的行数(这里是3),而不是每个数字字符串的字符长度。所以这行代码只会生成一个长度为1的向量(4-3=1),但num列有3个元素,str_glue要求所有传入的参数长度必须一致,要么都是1要么和数据行数相同,自然就报错了。而且就算你换成nchar(num)来获取每个元素的长度,直接用rep也没法对每个元素单独生成对应数量的0,因为rep是面向整个向量的操作,不是元素级的。
给你几个简单的解决方案
其实不用自己手动计算补多少个0,stringr包里的str_pad函数就是专门干这个事的,或者用sprintf格式化也很方便:
方法1:用str_pad(最直观)
这个方法先提取数字,再把数字补成4位带前导0的格式,最后和"P"拼接:
library(dplyr) library(stringr) dat <- data.frame(isolate = c("P10", "P104", "P2")) dat %>% mutate( num = str_extract(isolate, "[:digit:]+"), final = str_c("P", str_pad(num, width = 4, side = "left", pad = "0")) )
str_pad(num, width=4, side="left", pad="0")的作用就是把每个数字字符串的左边补0,直到总长度达到4位,完美匹配你的需求。
方法2:用sprintf(更简洁)
先把提取的数字转成整数,再用sprintf格式化输出,%04d表示格式化为4位整数,不足的位置自动补前导0:
library(dplyr) library(stringr) dat %>% mutate( num = as.integer(str_extract(isolate, "[:digit:]+")), final = sprintf("P%04d", num) )
方法3:一步到位的正则替换
如果你不想单独提取数字,也可以用正则表达式直接替换,一步完成格式转换:
library(dplyr) library(stringr) dat %>% mutate(final = str_replace_all(isolate, "(P)(\\d+)", function(x) { num <- str_extract(x, "\\d+") str_c("P", str_pad(num, 4, "left", "0")) }))
运行上面任意一段代码,你都会得到想要的结果:
isolate num final 1 P10 10 P0010 2 P104 104 P0104 3 P2 2 P0002
备注:内容来源于stack exchange,提问作者Tim
相关产品推荐
相关产品推荐

