我有一大系列的光栅,构成了气候数据的时间序列(1层/月(,我最终的目标是从中提取一系列坐标的值。我已经将它们作为列表从文件导入RStudio,然后堆叠它们:
Temp_list <- list.files('C:/Users/xxxx/Desktop/Project/climate_data/temp', full.names = TRUE)
TempST <- stack(Temp_list)
有>600层,它们在结构中被命名为:
CLIMATdata_temp_1_1988_V.1.5
CLIMATdata_temp_12_2001_V.1.5
即,月份列在变量类型(此处为temp(之后,年份之前。我遇到的问题是,10月之前的几个月被列为个位数(事先没有0(,而10月之后的几个月则被列为2位数。
我想循环浏览每一层,从文件名中提取月份和年份,然后将其转换为日期格式。
我希望从上述文件名中获得">1_1.1988"one_answers">12_2001",然后将这些转换为日期对象。
我知道我需要使用正则表达式来做到这一点,但我并不完全理解它的结构,而且我正在努力解决位数的差异。我尝试过以下代码,但没有任何成功:
for (i in TempST) {
Dt <- sub(pattern = '.*temp_(d+_d+).*', i) #also '^(?:.*_)?([0-9]{1:2})([0-9]{4})(?:..*)?$'
YrMo <- as.Date(dt, '%m_%Y')
i <- setZ(i, ym, 'date')
names(i) <- Dt
}
我确信这是一个相当简单的解决方案,但我已经为此挣扎了一段时间。非常感谢你的帮助。
我认为您的问题是对包含数字的字符串进行排序,并将这些字符串视为数字而非字母顺序。然后提取部分名称并确定日期(这个问题与光栅无关(。还要注意,无论你怎么做,你都可以而且应该在整个向量上做,而不是在一个循环中。
示例数据
f <- sort(paste0("a_2010_", 1:12, "_b.tif"))
f <- c(f, gsub(2010, 2011, f))
使用字符串::str_sort
library(stringr)
ff <- str_sort(f, numeric=TRUE)
或者推出自己的:
x <- data.frame(do.call(rbind, strsplit(basename(f), "_")))
x[,2] <- as.numeric(x[,2])
x[,3] <- as.numeric(x[,3])
i <- order(x[,2], x[,3])
ff <- f[i]
ff
# [1] "a_2010_1_b.tif" "a_2010_2_b.tif" "a_2010_3_b.tif" "a_2010_4_b.tif"
# [5] "a_2010_5_b.tif" "a_2010_6_b.tif" "a_2010_7_b.tif" "a_2010_8_b.tif"
# [9] "a_2010_9_b.tif" "a_2010_10_b.tif" "a_2010_11_b.tif" "a_2010_12_b.tif"
#[13] "a_2011_1_b.tif" "a_2011_2_b.tif" "a_2011_3_b.tif" "a_2011_4_b.tif"
#[17] "a_2011_5_b.tif" "a_2011_6_b.tif" "a_2011_7_b.tif" "a_2011_8_b.tif"
#[21] "a_2011_9_b.tif" "a_2011_10_b.tif" "a_2011_11_b.tif" "a_2011_12_b.tif"
获取日期:
ff <- str_sort(f, numeric=TRUE)
x <- data.frame(do.call(rbind, strsplit(basename(ff), "_")))
dates <- apply(cbind(x[,2:3], 15), 1, function(i) paste(i, collapse="-"))
d <- as.Date(dates)
d
# [1] "2010-01-15" "2010-02-15" "2010-03-15" "2010-04-15" "2010-05-15"
# [6] "2010-06-15" "2010-07-15" "2010-08-15" "2010-09-15" "2010-10-15"
#[11] "2010-11-15" "2010-12-15" "2011-01-15" "2011-02-15" "2011-03-15"
#[16] "2011-04-15" "2011-05-15" "2011-06-15" "2011-07-15" "2011-08-15"
#[21] "2011-09-15" "2011-10-15" "2011-11-15" "2011-12-15"
或者,从文件名中删除你不想要的内容(一旦你有了日期,就很容易排序,所以你不需要预先排序(
xf <- gsub("a_", "", f)
xf <- gsub("_b.tif", "", xf)
dd <- as.Date(paste0(xf, "_15"), "%Y_%m_%d")
i <- order(dd)
ff <- ff[i]
dd <- dd[i]
或者,如果你真的不在乎订单,并且你知道自己有几年的时间,你可以做
years <- 2010:2011
d <- paste0(rep(years,each=12), "-", rep(c(1,10:12,2:9), length(years)), "-", 15)
as.Date(d)
regex有点棘手,但这里有一种部分使用它的方法
g <- gsub("[^[:digit:]]", "", f)
as.Date(paste0(substr(g, 1, 4), "-", substr(g, 5, 7), "-", 15))
您可以使用解决问题
sub('.*temp_(\d+_\d+).*', '\1', i)
这里,
.*temp_
匹配任何零个或多个字符,尽可能多,然后匹配temp_
字符串(d+_d+)
将任意一个或多个数字、_
以及任意一个或者多个数字捕获到组1中.*
-任何零个或多个字符,尽可能多
1
替换仅在结果中保留组1的值。