使用 stringr 或 gsub 在字符数据的开头附加一个数字
Append a digit at the beginning of character data using stringr or gsub
我有一个名为DATA_TEST
的数据集。这个数据框包含字符format.You中的6个观察值,可以在下面看到table。
dput(DATA_TEST)
structure(list(Ten_digits = c("NA", "207", "0101", "0208 90",
"0206 90 99 00", "103")), .Names = "Ten_digits", row.names = c(NA,
-6L), class = "data.frame")
# -------------------------------------------------------------------------
# > DATA_TEST
# Ten_digits
# 1 NA
# 2 207
# 3 0101
# 4 0208 90
# 5 0206 90 99 00
# 6 103
所以我的目的是使用 stringr 或其他包转换此数据框,如下图所示。实际上代码需要做一件事或更精确
首先必须只找到像207
或103
这样的三位变量,并将这些变量转换为0207
和0103
。
在下面的 table 中,您终于可以看到 table 应该是什么样子了。
# > Desired Output
# Ten_digits
# 1 NA
# 2 0207
# 3 0101
# 4 0208 90
# 5 0206 90 99 00
# 6 0103
那么有人可以帮我处理这段代码吗?
您可以使用 stringr
中的 str_length
:
library(tidyverse) # in order to load all required packages at once
DATA_TEST %>%
mutate(Ten_digits = case_when(
str_length(Ten_digits) == 3 ~ paste0("0", Ten_digits),
TRUE ~ Ten_digits
))
# Ten_digits
#1 NA
#2 0207
#3 0101
#4 0208 90
#5 0206 90 99 00
#6 0103
str_length
允许您向量化字符向量的长度:来自 function's documentation:
Technically this returns the number of "code points", in a string. One code point usually corresponds to one character(...)
.
case_when
允许向量化多个 if_else
语句。
如评论中所述,可以使用ifelse
或if_else
,比case_when
更直接。请参阅以下微基准测试中的示例:
microbenchmark::microbenchmark(
DATA_TEST %>%
mutate(Ten_digits = case_when(
str_length(Ten_digits) == 3 ~ paste0("0", Ten_digits),
TRUE ~ Ten_digits
)),
DATA_TEST %>%
mutate(Ten_digits = ifelse(
str_length(Ten_digits) == 3, paste0("0", Ten_digits),
Ten_digits
)),
DATA_TEST %>%
mutate(Ten_digits = if_else(
str_length(Ten_digits) == 3, paste0("0", Ten_digits),
Ten_digits
))
)
# min lq mean median uq max neval
# 785.809 806.9130 1051.9314 858.217 1193.865 2445.434 100 # case_when
# 613.398 623.3985 862.6720 636.858 822.027 8610.763 100 # ifelse
# 625.485 641.1370 822.3502 664.135 894.812 1995.932 100 # if_else
我们可以简单地通过在 3 个字符的字符串前面粘贴一个 0
来做到这一点,即
DATA_TEST$Ten_digits[nchar(DATA_TEST$Ten_digits) == 3] <- paste0("0", DATA_TEST$Ten_digits[nchar(DATA_TEST$Ten_digits) == 3])
DATA_TEST
# Ten_digits
#1 NA
#2 0207
#3 0101
#4 0208 90
#5 0206 90 99 00
#6 0103
您可以使用简单的正则表达式 sub
:
DATA_TEST<-data.frame(Ten_digits=c("NA","207","0101","0208 90","0206 90 99 00","103"),stringsAsFactors = FALSE)
DATA_TEST$Ten_digits <- sub("^(\d{3})$", "0\1", DATA_TEST$Ten_digits)
DATA_TEST
## => Ten_digits
1 NA
2 0207
3 0101
4 0208 90
5 0206 90 99 00
6 0103
在这里,^(\d{3})$
匹配一个三位数字符串并将数字捕获到第 1 组(因为模式在括号内)并且 0
替换模式插入一个 0
并添加返回第 1 组中的整个匹配值。
图案详情
^
- 字符串开头
(\d{3})
- 第 1 组:三位数
$
- 字符串结尾。
您可以使用 stingr
中的 str_pad
。请注意,它会填充长度小于 4 个字符的任何字符串,因此如果您特别想关注长度为 3 的字符串,则需要修改代码。此外,如果您有文字 [=,则不需要 ifelse
14=] 而不是 "NA"。 -
DATA_TEST %>%
mutate(
Ten_digits = ifelse(Ten_digits == "NA", "NA", str_pad(Ten_digits, width = 4, pad = 0))
)
Ten_digits
1 NA
2 0207
3 0101
4 0208 90
5 0206 90 99 00
6 0103
我有一个名为DATA_TEST
的数据集。这个数据框包含字符format.You中的6个观察值,可以在下面看到table。
dput(DATA_TEST)
structure(list(Ten_digits = c("NA", "207", "0101", "0208 90",
"0206 90 99 00", "103")), .Names = "Ten_digits", row.names = c(NA,
-6L), class = "data.frame")
# -------------------------------------------------------------------------
# > DATA_TEST
# Ten_digits
# 1 NA
# 2 207
# 3 0101
# 4 0208 90
# 5 0206 90 99 00
# 6 103
所以我的目的是使用 stringr 或其他包转换此数据框,如下图所示。实际上代码需要做一件事或更精确
首先必须只找到像207
或103
这样的三位变量,并将这些变量转换为0207
和0103
。
在下面的 table 中,您终于可以看到 table 应该是什么样子了。
# > Desired Output
# Ten_digits
# 1 NA
# 2 0207
# 3 0101
# 4 0208 90
# 5 0206 90 99 00
# 6 0103
那么有人可以帮我处理这段代码吗?
您可以使用 stringr
中的 str_length
:
library(tidyverse) # in order to load all required packages at once
DATA_TEST %>%
mutate(Ten_digits = case_when(
str_length(Ten_digits) == 3 ~ paste0("0", Ten_digits),
TRUE ~ Ten_digits
))
# Ten_digits
#1 NA
#2 0207
#3 0101
#4 0208 90
#5 0206 90 99 00
#6 0103
str_length
允许您向量化字符向量的长度:来自 function's documentation:
Technically this returns the number of "code points", in a string. One code point usually corresponds to one character(...)
.
case_when
允许向量化多个 if_else
语句。
如评论中所述,可以使用ifelse
或if_else
,比case_when
更直接。请参阅以下微基准测试中的示例:
microbenchmark::microbenchmark(
DATA_TEST %>%
mutate(Ten_digits = case_when(
str_length(Ten_digits) == 3 ~ paste0("0", Ten_digits),
TRUE ~ Ten_digits
)),
DATA_TEST %>%
mutate(Ten_digits = ifelse(
str_length(Ten_digits) == 3, paste0("0", Ten_digits),
Ten_digits
)),
DATA_TEST %>%
mutate(Ten_digits = if_else(
str_length(Ten_digits) == 3, paste0("0", Ten_digits),
Ten_digits
))
)
# min lq mean median uq max neval
# 785.809 806.9130 1051.9314 858.217 1193.865 2445.434 100 # case_when
# 613.398 623.3985 862.6720 636.858 822.027 8610.763 100 # ifelse
# 625.485 641.1370 822.3502 664.135 894.812 1995.932 100 # if_else
我们可以简单地通过在 3 个字符的字符串前面粘贴一个 0
来做到这一点,即
DATA_TEST$Ten_digits[nchar(DATA_TEST$Ten_digits) == 3] <- paste0("0", DATA_TEST$Ten_digits[nchar(DATA_TEST$Ten_digits) == 3])
DATA_TEST
# Ten_digits
#1 NA
#2 0207
#3 0101
#4 0208 90
#5 0206 90 99 00
#6 0103
您可以使用简单的正则表达式 sub
:
DATA_TEST<-data.frame(Ten_digits=c("NA","207","0101","0208 90","0206 90 99 00","103"),stringsAsFactors = FALSE)
DATA_TEST$Ten_digits <- sub("^(\d{3})$", "0\1", DATA_TEST$Ten_digits)
DATA_TEST
## => Ten_digits
1 NA
2 0207
3 0101
4 0208 90
5 0206 90 99 00
6 0103
在这里,^(\d{3})$
匹配一个三位数字符串并将数字捕获到第 1 组(因为模式在括号内)并且 0
替换模式插入一个 0
并添加返回第 1 组中的整个匹配值。
图案详情
^
- 字符串开头(\d{3})
- 第 1 组:三位数$
- 字符串结尾。
您可以使用 stingr
中的 str_pad
。请注意,它会填充长度小于 4 个字符的任何字符串,因此如果您特别想关注长度为 3 的字符串,则需要修改代码。此外,如果您有文字 [=,则不需要 ifelse
14=] 而不是 "NA"。 -
DATA_TEST %>%
mutate(
Ten_digits = ifelse(Ten_digits == "NA", "NA", str_pad(Ten_digits, width = 4, pad = 0))
)
Ten_digits
1 NA
2 0207
3 0101
4 0208 90
5 0206 90 99 00
6 0103