很抱歉,如果我的问题在这里找到答案。不幸的是我找不到它。
我有一个字符串,其格式如下" 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))
但是出于学习目的,我想知道如何以更好的方式做到这一点。
答案 0 :(得分:2)
tidyr
具有非常强大的separate
,可以很好地处理数据框/数据表,
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
以下是基础R中gsub
的典型方法。在每种情况下,匹配字符串的前导部分,匹配捕获括号中的有趣部分,匹配其余部分。替换为&#34; \\ 1&#34;表示捕获的值
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))
答案 1 :(得分:2)
以下是一些基本选项:
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
(虽然最后一个是矢量列表,但您的消费格式略有不同。)