Gsub,提取一定数量的数字
Gsub, extract certain amount of digits
抱歉,如果这里某处有我的问题的答案。可惜没找到。
我有一个具有以下形式的字符串 "ANNNNNNN.tif",其中 A 只是一个字母,N 是一个数字。一排有7位数字。
new <- c("A2000001.tif" ,"A2000002.tif", "A2000003.tif", "A2000004.tif", "A2000005.tif", "A2000006.tif")
我想从中获取年份和月份的值。前 4 位数字代表年份,后 2 位代表月份。例如。我写这个是为了得到一个年份值
year1 <- gsub("([0-9]){3,4}?.*$", "", new)
year <- as.numeric(gsub("A", "", year1))
但我想它可以写得更短一些,但我仍然很难获得一个月的价值。
UPD:我写这篇文章是为了一个月。
month1 <- gsub("^*.([0-9]){6,7}?", "\1", new)
month <- as.numeric(gsub(".tif", "", month1))
但仍然出于学习目的,我想知道如何以更好的方式做到这一点。
tidyr
具有非常强大的 separate
,适用于数据 frames/data 表,
new <- c("A2000001.tif" ,"A2000002.tif", "A2000003.tif", "A2000004.tif", "A2000005.tif", "A2000006.tif")
library(tidyr)
df <- as.data.frame(new) %>%
separate(new, into = c("letter", "year", "extra", "month", "extension"), sep=c(1,5,6,8), remove = FALSE) %>%
select(-extra, -extension)
df
# new letter year month
# 1 A2000001.tif A 2000 01
# 2 A2000002.tif A 2000 02
# 3 A2000003.tif A 2000 03
# 4 A2000004.tif A 2000 04
# 5 A2000005.tif A 2000 05
# 6 A2000006.tif A 2000 06
以下是 gsub
在 base R 中的典型方法。在每种情况下,尽可能多地匹配字符串的前导部分,匹配捕获括号中感兴趣的部分,匹配其余部分。替换为“\\1”表示捕获的值
new <- c("A2000001.tif" ,"A2000002.tif", "A2000003.tif", "A2000004.tif", "A2000005.tif", "A2000006.tif")
letter <- gsub("(.).*", "\1", new)
year <- as.numeric(gsub(".(\d{4}).*", "\1", new))
month <- as.numeric(gsub(".\d{4}.(\d{2}).+", "\1", new))
以下是一些基本选项:
new <- c("A2000001.tif" ,"A2000002.tif", "A2000003.tif",
"A2000004.tif", "A2000005.tif", "A2000006.tif")
假设它们始终位于字符串中的相同位置:
as.integer(substr(new, 2, 5))
# [1] 2000 2000 2000 2000 2000 2000
as.integer(substr(new, 7, 8))
# [1] 1 2 3 4 5 6
更具适应性,假设它们总是跟在非数字(年)之后或在点(月)之前:
as.integer(sub("^[^0-9]([0-9]{4}).*", "\1", new))
# [1] 2000 2000 2000 2000 2000 2000
as.integer(sub(".*([0-9]{2})\..*", "\1", new))
# [1] 1 2 3 4 5 6
提取所有数字并对它们做一些花哨的数学计算:
x <- as.integer(gsub("[^0-9]", "", new))
x %/% 1000
# [1] 2000 2000 2000 2000 2000 2000
x %% 100
# [1] 1 2 3 4 5 6
超级强大的正则表达式提取 (https://xkcd.com/1171/):
lapply(
regmatches(new,
gregexpr("(?<![0-9])[0-9]{4}|[0-9]{2}(?![0-9])", new, perl = TRUE)),
as.integer
)
# [[1]]
# [1] 2000 1
# [[2]]
# [1] 2000 2
# [[3]]
# [1] 2000 3
# [[4]]
# [1] 2000 4
# [[5]]
# [1] 2000 5
# [[6]]
# [1] 2000 6
(虽然最后一个是矢量列表,但格式略有不同,供您使用。)
抱歉,如果这里某处有我的问题的答案。可惜没找到。
我有一个具有以下形式的字符串 "ANNNNNNN.tif",其中 A 只是一个字母,N 是一个数字。一排有7位数字。
new <- c("A2000001.tif" ,"A2000002.tif", "A2000003.tif", "A2000004.tif", "A2000005.tif", "A2000006.tif")
我想从中获取年份和月份的值。前 4 位数字代表年份,后 2 位代表月份。例如。我写这个是为了得到一个年份值
year1 <- gsub("([0-9]){3,4}?.*$", "", new)
year <- as.numeric(gsub("A", "", year1))
但我想它可以写得更短一些,但我仍然很难获得一个月的价值。
UPD:我写这篇文章是为了一个月。
month1 <- gsub("^*.([0-9]){6,7}?", "\1", new)
month <- as.numeric(gsub(".tif", "", month1))
但仍然出于学习目的,我想知道如何以更好的方式做到这一点。
tidyr
具有非常强大的 separate
,适用于数据 frames/data 表,
new <- c("A2000001.tif" ,"A2000002.tif", "A2000003.tif", "A2000004.tif", "A2000005.tif", "A2000006.tif")
library(tidyr)
df <- as.data.frame(new) %>%
separate(new, into = c("letter", "year", "extra", "month", "extension"), sep=c(1,5,6,8), remove = FALSE) %>%
select(-extra, -extension)
df
# new letter year month
# 1 A2000001.tif A 2000 01
# 2 A2000002.tif A 2000 02
# 3 A2000003.tif A 2000 03
# 4 A2000004.tif A 2000 04
# 5 A2000005.tif A 2000 05
# 6 A2000006.tif A 2000 06
以下是 gsub
在 base R 中的典型方法。在每种情况下,尽可能多地匹配字符串的前导部分,匹配捕获括号中感兴趣的部分,匹配其余部分。替换为“\\1”表示捕获的值
new <- c("A2000001.tif" ,"A2000002.tif", "A2000003.tif", "A2000004.tif", "A2000005.tif", "A2000006.tif")
letter <- gsub("(.).*", "\1", new)
year <- as.numeric(gsub(".(\d{4}).*", "\1", new))
month <- as.numeric(gsub(".\d{4}.(\d{2}).+", "\1", new))
以下是一些基本选项:
new <- c("A2000001.tif" ,"A2000002.tif", "A2000003.tif",
"A2000004.tif", "A2000005.tif", "A2000006.tif")
假设它们始终位于字符串中的相同位置:
as.integer(substr(new, 2, 5))
# [1] 2000 2000 2000 2000 2000 2000
as.integer(substr(new, 7, 8))
# [1] 1 2 3 4 5 6
更具适应性,假设它们总是跟在非数字(年)之后或在点(月)之前:
as.integer(sub("^[^0-9]([0-9]{4}).*", "\1", new))
# [1] 2000 2000 2000 2000 2000 2000
as.integer(sub(".*([0-9]{2})\..*", "\1", new))
# [1] 1 2 3 4 5 6
提取所有数字并对它们做一些花哨的数学计算:
x <- as.integer(gsub("[^0-9]", "", new))
x %/% 1000
# [1] 2000 2000 2000 2000 2000 2000
x %% 100
# [1] 1 2 3 4 5 6
超级强大的正则表达式提取 (https://xkcd.com/1171/):
lapply(
regmatches(new,
gregexpr("(?<![0-9])[0-9]{4}|[0-9]{2}(?![0-9])", new, perl = TRUE)),
as.integer
)
# [[1]]
# [1] 2000 1
# [[2]]
# [1] 2000 2
# [[3]]
# [1] 2000 3
# [[4]]
# [1] 2000 4
# [[5]]
# [1] 2000 5
# [[6]]
# [1] 2000 6
(虽然最后一个是矢量列表,但格式略有不同,供您使用。)