R:找到一个模式并编辑
R : find a pattern and edit
我知道关于添加 leading zero
的所有问题 以及为他们提供的 综合答复 ,例如Q1, Q2, Q3.
但对我来说,至少根据我目前的知识,我无法按照以下方式解决我将要做的事情:
- 使用
regex
模式匹配在 string
中添加 leading zero
所以,我只想在 -
. 之后将 leading zero
添加到 digits
例如:
Sam <- c("222-88", "537-457", "652-1", "787-892")
var <- LETTERS[1:4]
DF<- data.frame(Sam, var)
DF
Sam var
1 222-88 A
2 537-457 B
3 652-1 C
4 787-892 D
预期结果:
Sam var
1 222-088 A
2 537-457 B
3 652-001 C
4 787-892 D
我试过了:
library(stringr)
temp <- DF[str_detect(DF$Sam, "-[0-9]{1,2}$"),] # will find the rows need the leading zero
temp
Sam var
1 222-88 A
3 652-1 C
formatC(temp$Sam, width = 2,flag = 0)# not correct!
我们可以使用 base R
来做到这一点,方法是将字符串拆分为 -
,然后在转换为 numeric
之后使用 sprintf
填充 0,然后 paste
DF$Sam <- sapply(strsplit(as.character(DF$Sam), "-"), function(x)
paste(x[1],sprintf("%03d", as.numeric(x[2])), sep="-"))
DF$Sam
#[1] "222-088" "537-457" "652-001" "787-892"
如果我们需要正则表达式方法,我们可以使用 gsubfn
library(gsubfn)
gsubfn("(\d+)$", ~sprintf("%03d", as.numeric(x)), as.character(DF$Sam))
#[1] "222-088" "537-457" "652-001" "787-892"
Base R 中的另一种选择是
DF$Sam = sub("-(\d)\b", "-00\1", DF$Sam)
DF$Sam = sub("-(\d\d)\b", "-0\1", DF$Sam)
DF
Sam var
1 222-088 A
2 537-457 B
3 652-001 C
4 787-892 D
另一个基本选项
Sam <- c("222-88", "537-457", "652-1", "787-892")
m <- gregexpr("[0-9]+$", Sam)
regmatches(Sam, m) <- sprintf('%03s', unlist(regmatches(Sam, m)))
Sam
# [1] "222-088" "537-457" "652-001" "787-892"
坚持使用 tidyverse
你可以试试:
Sam <- c("222-88", "537-457", "652-1", "787-892")
var <- LETTERS[1:4]
df <- data.frame(Sam, var)
library(dplyr)
library(tidyr)
library(stringr)
df %>%
separate(Sam, c("sam1", "sam2")) %>%
mutate(Sam = str_c(sam1, "-", str_pad(sam2, 3, "left", "0"))) %>%
select(-sam1, -sam2)
#> var Sam
#> 1 A 222-088
#> 2 B 537-457
#> 3 C 652-001
#> 4 D 787-892
# OR
df %>%
mutate(
sam_new = str_c(
str_extract(Sam, "^\d+-"),
str_extract(Sam, "\d+$") %>% str_pad(3, "left", "0")
)
)
#> Sam var sam_new
#> 1 222-88 A 222-088
#> 2 537-457 B 537-457
#> 3 652-1 C 652-001
#> 4 787-892 D 787-892
我知道关于添加 leading zero
的所有问题 以及为他们提供的 综合答复 ,例如Q1, Q2, Q3.
但对我来说,至少根据我目前的知识,我无法按照以下方式解决我将要做的事情:
- 使用
regex
模式匹配在string
中添加leading zero
所以,我只想在-
. 之后将
leading zero
添加到 digits
例如:
Sam <- c("222-88", "537-457", "652-1", "787-892")
var <- LETTERS[1:4]
DF<- data.frame(Sam, var)
DF
Sam var
1 222-88 A
2 537-457 B
3 652-1 C
4 787-892 D
预期结果:
Sam var
1 222-088 A
2 537-457 B
3 652-001 C
4 787-892 D
我试过了:
library(stringr)
temp <- DF[str_detect(DF$Sam, "-[0-9]{1,2}$"),] # will find the rows need the leading zero
temp
Sam var
1 222-88 A
3 652-1 C
formatC(temp$Sam, width = 2,flag = 0)# not correct!
我们可以使用 base R
来做到这一点,方法是将字符串拆分为 -
,然后在转换为 numeric
之后使用 sprintf
填充 0,然后 paste
DF$Sam <- sapply(strsplit(as.character(DF$Sam), "-"), function(x)
paste(x[1],sprintf("%03d", as.numeric(x[2])), sep="-"))
DF$Sam
#[1] "222-088" "537-457" "652-001" "787-892"
如果我们需要正则表达式方法,我们可以使用 gsubfn
library(gsubfn)
gsubfn("(\d+)$", ~sprintf("%03d", as.numeric(x)), as.character(DF$Sam))
#[1] "222-088" "537-457" "652-001" "787-892"
Base R 中的另一种选择是
DF$Sam = sub("-(\d)\b", "-00\1", DF$Sam)
DF$Sam = sub("-(\d\d)\b", "-0\1", DF$Sam)
DF
Sam var
1 222-088 A
2 537-457 B
3 652-001 C
4 787-892 D
另一个基本选项
Sam <- c("222-88", "537-457", "652-1", "787-892")
m <- gregexpr("[0-9]+$", Sam)
regmatches(Sam, m) <- sprintf('%03s', unlist(regmatches(Sam, m)))
Sam
# [1] "222-088" "537-457" "652-001" "787-892"
坚持使用 tidyverse
你可以试试:
Sam <- c("222-88", "537-457", "652-1", "787-892")
var <- LETTERS[1:4]
df <- data.frame(Sam, var)
library(dplyr)
library(tidyr)
library(stringr)
df %>%
separate(Sam, c("sam1", "sam2")) %>%
mutate(Sam = str_c(sam1, "-", str_pad(sam2, 3, "left", "0"))) %>%
select(-sam1, -sam2)
#> var Sam
#> 1 A 222-088
#> 2 B 537-457
#> 3 C 652-001
#> 4 D 787-892
# OR
df %>%
mutate(
sam_new = str_c(
str_extract(Sam, "^\d+-"),
str_extract(Sam, "\d+$") %>% str_pad(3, "left", "0")
)
)
#> Sam var sam_new
#> 1 222-88 A 222-088
#> 2 537-457 B 537-457
#> 3 652-1 C 652-001
#> 4 787-892 D 787-892