问题描述
我在文件名中提取日期时遇到问题,在我的示例中,有 file.name
对象:
file.name<- c("AZAMBUJAI002A20190518T133231_20190518T133919_T22JCM_2021_05_19_01_18_22.tif","RINCAodoSSOARES051B20210107T133231_20190518T133919_T22JSM_2021_05_19_01_18_22","VILAPALMA33K20181018T133231_20190518T133919_T23JCM_2020_05_19_01_18_22.tif")
我需要在一个新对象中提取文件名中的特定日期:20190518
、20210107
和 20181018
。但是为此 a 不能使用 substr
因为 a 具有不同长度的区域名称(AZAMBUJAI002A
、RINCAodoSSOARES051B
和 VILAPALMA33K
)并且也不能使用删除字母(一个原因数字区域 ID - 002、051 和 33)。以“_”分隔的“.tif”之前最后的日期不是有用的信息。
我想要的输出是:
mydates
[1] 2019-05-18
[2] 2021-01-07
[3] 2018-10-18
所描述的问题是否有任何解决方案?谢谢!!
解决方法
这是一种使用正则表达式提取的方法 - 假设您只有以 20xx
开头的年份
library(stringr)
library(lubridate)
date_string <- str_extract(file.name,"20\\d{2}\\[0,1][1-9]\\[0-3][1-9]")
date_string
#> [1] "20190518" "20210107" "20181018"
ymd(date_string)
#> [1] "2019-05-18" "2021-01-07" "2018-10-18"
由 reprex package (v2.0.0) 于 2021 年 5 月 19 日创建
,使用基本 R 函数的解决方案。只要格式始终为“yyyymmdd”并且相关字符串出现在第一个下划线之前,就可以工作:
file.name<- c("AZAMBUJAI002A20190518T133231_20190518T133919_T22JCM_2021_05_19_01_18_22.tif","RINCAODOSSOARES051B20210107T133231_20190518T133919_T22JSM_2021_05_19_01_18_22","VILAPALMA33K20181018T133231_20190518T133919_T23JCM_2020_05_19_01_18_22.tif")
使用 gsub
两次:首先(在内部函数中)去掉第一个下划线之后的所有内容,然后提取八个数字的序列([0-9]{8}
:
dates <- gsub(".*([0-9]{8}).*","\\1",gsub("^([^_]*)_.*",file.name))
最后使用 as.Date
将字符串转换为 R 日期对象(可以使用 format
重新转换为字符串):
dates_as_actual_date <- as.Date(dates,format("%Y%m%d"))
dates_as_actual_date
是一个 R 日期对象,如下所示:
[1] "2019-05-18" "2021-01-07" "2018-10-18"
,library(lubridate)
ymd(gsub("(^.*_)(20[0-9]{2}_)([0-9]{2}_)([0-9]{2}_)(.*$)","\\2\\3\\4",file.name))
ymd
是一个 lubridate 函数,用于识别 YYYY-MM-DD 日期,几乎与使用的分隔符无关。
gsub
转换字符串。里面的正则表达式:
- (^.*_) 是第一个捕获组。接受从开头到下划线的任何内容。
- (20[0-9]{2}_) 是第二个捕获组。它需要一个以 20 开头的字符串,后跟任意两位数字和一个下划线。
- ([0-9]{2}_) 是第三个和第四个捕获组。它需要两个数字,后跟一个下划线。
- (.*$) 是最后一个(第 5 个)捕获组。将任何内容带到字符串的末尾。
- "\2\3\4" 返回第二、第三和第四个捕获组。
编辑:
对代码的解释仍然可以,但是要检索名称后面的日期,则所需的代码是这样的:
ymd(gsub("(^.*[A-Z])(20[0-9]{2})([0-9]{2})([0-9]{2})(.*$)",file.name))