r - 将文本中包含的半年格式化为日期
问题描述
我有文本中包含的日期值,每个包含一年的一半:
date_by_half <- c("2016 H1", "2017 H2", "2018 H1")
我想从文本中提取日期并存储为每半年或“学期”的第一天。所以,像:
ysemester(date_by_half)
#[1] "2016-01-01" "2017-07-01" "2018-01-01"
我熟悉lubridate::yq()
功能,但我发现这只适用于宿舍。
lubridate::yq(date_by_half)
#[1] "2016-01-01" "2017-04-01" "2018-01-01"
现在我的工作是用 Q3 替换 H2:
lubridate::yq(stringr::str_replace(date_by_half,"H2", "Q3"))
#[1] "2016-01-01" "2017-07-01" "2018-01-01"
但是,我想知道是否有更雄辩的解决方案使用lubridate
(或其他一些快速且可重用的方法)。
解决方案
一班轮
这些单行代码仅使用基础 R:
1) read.table/ISOdate
with(read.table(text = date_by_half), as.Date(ISOdate(V1, ifelse(V2=="H1",1,7), 1)))
## [1] "2016-01-01" "2017-07-01" "2018-01-01"
2) sub 更短的是:
as.Date(sub(" H2", "-7-1", sub(" H1", "-1-1", date_by_half)))
## [1] "2016-01-01" "2017-07-01" "2018-01-01"
S3
另一种方法是"half"
为半年日期创建一个 S3 类。我们只会实现我们需要的方法。
as.half <- function(x, ...) UseMethod("as.half")
as.half.character <- function(x, ...) {
year <- as.numeric(sub("\\D.*", "", x))
half <- as.numeric(sub(".*\\D", "", x))
structure(year + (half - 1)/2, class = "half")
}
as.Date.half <- function(x, ...) {
as.Date(ISOdate(as.integer(x), 12 * (x - as.integer(x)) + 1, 1))
}
# test
as.Date(as.half(date_by_half))
## [1] "2016-01-01" "2017-07-01" "2018-01-01"
推荐阅读
- javascript - Discord.js - 当命令没有别名时,帮助命令返回“未定义”
- c# - [Xamarin.Forms]ListView中的自定义控件
- ruby-on-rails - 如果具有相同属性的旧对象关联到同一个当前对象的关联表,则不创建对象
- python - pd.cut binning 对于部分数值积分不能正常工作
- r - 使用 likert() 时分组汇总结果出错
- python - Django 注册表单
- azure-data-factory-2 - 在数据流 (ADF) 中拆分 json 字符串列或展平转换
- c# - Microsoft Graph SDK 不返回 Azure AD B2C 用户的自定义属性值
- python - 如何使用熊猫将某些行视为新列
- reactjs - 路由路径无法正常工作我试图根据 roomId 显示聊天但我无法正常工作