R语言如何根据索引区间修改POSIXct日期列的年份
需求描述
现有R语言数据框nAUR,样例结构如下:
> dput(head(nAUR,50)) structure(list(date = structure(c(1483440272, 1484304241, 1484564041, 1484823831, 1485428001, 1485687791, 1486032161, 1486291941, 1486551731, 1486896101, 1487155881, 1487415671, 1487760031, 1488019821, 1488279601, 1488624021, 1488883821, 1489143521, 1489488011, 1489747821, 1490007451, 1490352021, 1490608221, 1490867781, 1491212421, 1491472221, 1491731811, 1492076421, 1492336231, 1492595781, 1492940421, 1493200231, 1493459811, 1493804421, 1494064231, 1494323781, 1494668431, 1494928231, 1495187811, 1495532431, 1495792231, 1496051781, 1496396421, 1496656231, 1496915811, 1497260421, 1497520231, 1497779781, 1498124421, 1498384231), tzone = "", class = c("POSIXct", "POSIXt")), layer = c("AUR", "AUR", "AUR", "AUR", "AUR", "AUR", "AUR", "AUR", "AUR", "AUR", "AUR", "AUR", "AUR", "AUR", "AUR", "AUR", "AUR", "AUR", "AUR", "AUR", "AUR", "AUR", "AUR", "AUR", "AUR", "AUR", "AUR", "AUR", "AUR", "AUR", "AUR", "AUR", "AUR", "AUR", "AUR", "AUR", "AUR", "AUR", "AUR", "AUR", "AUR", "AUR", "AUR", "AUR", "AUR", "AUR", "AUR", "AUR", "AUR", "AUR")), row.names = c(NA, -50L), class = c("tbl_df", "tbl", "data.frame"))
需要将时间处于2017-01-13 10:44:01(对应时间戳1484304241)至2017-03-17 10:50:21(对应时间戳1489747821)区间内记录的年份修改为2016。由于待修改日期存在重复值,要求必须通过数据帧的位置索引定位目标记录完成操作。
实现步骤
1. 定位目标区间的行索引
首先匹配起止时间对应的行位置,数据按时间升序排列的前提下,两个位置之间的连续行即为所有需要修改的记录:
# 定义区间起止时间戳 start_timestamp <- 1484304241 end_timestamp <- 1489747821 # 转换为POSIXct时间格式,和date列格式保持一致 start_time <- as.POSIXct(start_timestamp, origin = "1970-01-01", tz = "") end_time <- as.POSIXct(end_timestamp, origin = "1970-01-01", tz = "") # 获取起止位置的行索引,存在重复值时默认取第一个匹配的位置 start_row <- which(nAUR$date == start_time)[1] end_row <- which(nAUR$date == end_time)[1] # 如需取最后一个匹配结束时间的行作为区间终点,替换为下面这行代码 # end_row <- tail(which(nAUR$date == end_time), 1)
2. 按位置索引修改对应记录的年份
提供两种实现方式,按需选择即可:
- 方式一:使用
lubridate包,代码更简洁
# 先安装加载包,已安装可跳过 # install.packages("lubridate") library(lubridate) # 按位置索引批量修改年份 year(nAUR$date[start_row:end_row]) <- 2016
- 方式二:基础R实现,无需安装额外包
nAUR$date[start_row:end_row] <- as.POSIXct( format(nAUR$date[start_row:end_row], "2016-%m-%d %H:%M:%S"), tz = "" )
结果校验
修改完成后可以通过以下代码检查修改范围是否正确:
# 查看修改区间首尾的时间,确认年份已改为2016 head(nAUR$date[start_row:end_row]) tail(nAUR$date[start_row:end_row]) # 查看区间外的时间,确认未被误改 head(nAUR$date, start_row - 1) tail(nAUR$date, nrow(nAUR) - end_row)
注意事项
- 整个操作基于行位置索引完成,不会因为时间值重复出现错改、漏改问题
- 操作前请确认
date列是按时间升序排列,和样例数据结构一致,保证连续索引能完整覆盖目标区间 - 注意保持时区参数和原始数据的
tzone属性一致,避免时间转换出现偏差
内容的提问来源于stack exchange,提问作者Cláudio Siva
相关产品推荐
相关产品推荐

