如何操作日期列的时间部分?
How to manipulate the time part of a date column?
如何编写此代码(hour
来自 lubridate
包)?
Objective:如果PICK_DATE的小时部分晚于16:00,ADJ_PICK_DATE应该是第二天03:00。如果PICK_DATE的小时部分早于03:00,那么ADJ_PICK_DATE就是同一天03:00。问题是,当不需要更改时,代码仍会向 PICK_DATE 添加 3 小时,即当 PICK_DATE 的小时部分在 03:00 和 16:00 内时。
x$PICK_TIME <- cut(hour(x$PICK_DATE), c(-1, 2, 15, 24), c("EARLY", "OKAY", "LATE"))
x$ADJ_PICK_DATE <- ifelse(x$PICK_TIME=="EARLY",
as.POSIXct(paste(format(x$PICK_DATE, "%d-%b-%Y"), "03:00"),
format="%d-%b-%Y %H:%M"), x$PICK_DATE)
x$ADJ_PICK_DATE <- ifelse(x$PICK_TIME=="LATE",
as.POSIXct(paste(format(x$PICK_DATE+86400, "%d-%b-%Y"),
"03:00"), format="%d-%b-%Y %H:%M"),
x$ADJ_PICK_DATE)
x$ADJ_PICK_DATE <- as.POSIXct(x$ADJ_PICK_DATE, origin = "1970-01-01")
请帮忙。
示例数据:
PICK_DATE SHIP_DATE
01-APR-2017 00:51 02-APR-2017 06:55 AM
01-APR-2017 00:51 02-APR-2017 12:11 PM
01-APR-2017 00:51 02-APR-2017 12:11 PM
01-APR-2017 00:51 02-APR-2017 09:39 AM
听起来您只需要执行两个不同的算术运算,以日期时间的小时为条件?
我认为访问小时组件的最简单方法是将时间存储在 POSIXlt
中。我相信 "l" 代表或 "list",这使您可以将时间戳视为一个列表,其中不同的时间度量是相应的可访问属性。
像这样:
> time <- as.POSIXlt('2017-07-29 15:12:01')
> time
[1] "2017-07-29 15:12:01 EDT"
> time$hour
[1] 15
所以您可以编写一个函数来执行您想要的操作,并将其提供给您的日期列。我很难进一步了解这个问题,因为我不太明白这个问题,但这里有一个框架:
ComputeDifference <- function(time) {
if (time$hour < 3) {
# code to count orders between 0 and 3 "from same day 3:00"
}
if (time$hour > 16) {
# code to consider late orders
}
}
如果您输入示例数据并完善问题,也许我可以对此进行更彻底的破解。
这是一个简单的、可重现的例子。根据您之前提出的问题,我不得不编造一些样本数据。我建议阅读 dplyr
和 lubridate
,因为它们将帮助您处理日期。
编辑:已更新以使用月末日期。
library(lubridate)
library(dplyr)
df <- data.frame(pick_date = c("01-APR-2017 00:51", "02-APR-2017 08:53", "15-APR-2017 16:12", "23-APR-2017 02:04", "30-APR-2017 20:08"), ship_date = c("05-APR-2017 06:55", "09-APR-2017 12:11", "30-APR-2017 13:11", "02-MAY-2017 15:16", "05-MAY-2017 09:57"))
df %>%
mutate(pick_date = dmy_hm(pick_date)) %>%
mutate(ship_date = dmy_hm(ship_date)) %>%
mutate(pick_time = case_when(
hour(pick_date) <= 3 ~ "early",
hour(pick_date) >= 16 ~ "late",
TRUE ~ "okay")
) %>%
mutate(new_pick_time = case_when(
pick_time == "early" ~ hms(hours(3)),
pick_time == "late" ~ hms(hours(3)),
TRUE ~ hms(paste0(hour(pick_date), "H ", minute(pick_date), "M ", second(pick_date), "S")))
) %>%
mutate(temp_pick_date = case_when(
pick_time == "early" ~ pick_date,
pick_time == "late" ~ pick_date + days(1),
TRUE ~ pick_date)
) %>%
mutate(new_pick_date = make_datetime(year(temp_pick_date), month(temp_pick_date), day(temp_pick_date), hour(new_pick_time), minute(new_pick_time), second(new_pick_time))) %>%
select(-new_pick_time, -temp_pick_date)
这个returns
pick_date ship_date pick_time new_pick_date
1 2017-04-01 00:51:00 2017-04-05 06:55:00 early 2017-04-01 03:00:00
2 2017-04-02 08:53:00 2017-04-09 12:11:00 okay 2017-04-02 08:53:00
3 2017-04-15 16:12:00 2017-04-30 13:11:00 late 2017-04-16 03:00:00
4 2017-04-23 02:04:00 2017-05-02 15:16:00 early 2017-04-23 03:00:00
5 2017-04-30 20:08:00 2017-05-05 09:57:00 late 2017-05-01 03:00:00
如何编写此代码(hour
来自 lubridate
包)?
Objective:如果PICK_DATE的小时部分晚于16:00,ADJ_PICK_DATE应该是第二天03:00。如果PICK_DATE的小时部分早于03:00,那么ADJ_PICK_DATE就是同一天03:00。问题是,当不需要更改时,代码仍会向 PICK_DATE 添加 3 小时,即当 PICK_DATE 的小时部分在 03:00 和 16:00 内时。
x$PICK_TIME <- cut(hour(x$PICK_DATE), c(-1, 2, 15, 24), c("EARLY", "OKAY", "LATE"))
x$ADJ_PICK_DATE <- ifelse(x$PICK_TIME=="EARLY",
as.POSIXct(paste(format(x$PICK_DATE, "%d-%b-%Y"), "03:00"),
format="%d-%b-%Y %H:%M"), x$PICK_DATE)
x$ADJ_PICK_DATE <- ifelse(x$PICK_TIME=="LATE",
as.POSIXct(paste(format(x$PICK_DATE+86400, "%d-%b-%Y"),
"03:00"), format="%d-%b-%Y %H:%M"),
x$ADJ_PICK_DATE)
x$ADJ_PICK_DATE <- as.POSIXct(x$ADJ_PICK_DATE, origin = "1970-01-01")
请帮忙。
示例数据:
PICK_DATE SHIP_DATE
01-APR-2017 00:51 02-APR-2017 06:55 AM
01-APR-2017 00:51 02-APR-2017 12:11 PM
01-APR-2017 00:51 02-APR-2017 12:11 PM
01-APR-2017 00:51 02-APR-2017 09:39 AM
听起来您只需要执行两个不同的算术运算,以日期时间的小时为条件?
我认为访问小时组件的最简单方法是将时间存储在 POSIXlt
中。我相信 "l" 代表或 "list",这使您可以将时间戳视为一个列表,其中不同的时间度量是相应的可访问属性。
像这样:
> time <- as.POSIXlt('2017-07-29 15:12:01')
> time
[1] "2017-07-29 15:12:01 EDT"
> time$hour
[1] 15
所以您可以编写一个函数来执行您想要的操作,并将其提供给您的日期列。我很难进一步了解这个问题,因为我不太明白这个问题,但这里有一个框架:
ComputeDifference <- function(time) {
if (time$hour < 3) {
# code to count orders between 0 and 3 "from same day 3:00"
}
if (time$hour > 16) {
# code to consider late orders
}
}
如果您输入示例数据并完善问题,也许我可以对此进行更彻底的破解。
这是一个简单的、可重现的例子。根据您之前提出的问题,我不得不编造一些样本数据。我建议阅读 dplyr
和 lubridate
,因为它们将帮助您处理日期。
编辑:已更新以使用月末日期。
library(lubridate)
library(dplyr)
df <- data.frame(pick_date = c("01-APR-2017 00:51", "02-APR-2017 08:53", "15-APR-2017 16:12", "23-APR-2017 02:04", "30-APR-2017 20:08"), ship_date = c("05-APR-2017 06:55", "09-APR-2017 12:11", "30-APR-2017 13:11", "02-MAY-2017 15:16", "05-MAY-2017 09:57"))
df %>%
mutate(pick_date = dmy_hm(pick_date)) %>%
mutate(ship_date = dmy_hm(ship_date)) %>%
mutate(pick_time = case_when(
hour(pick_date) <= 3 ~ "early",
hour(pick_date) >= 16 ~ "late",
TRUE ~ "okay")
) %>%
mutate(new_pick_time = case_when(
pick_time == "early" ~ hms(hours(3)),
pick_time == "late" ~ hms(hours(3)),
TRUE ~ hms(paste0(hour(pick_date), "H ", minute(pick_date), "M ", second(pick_date), "S")))
) %>%
mutate(temp_pick_date = case_when(
pick_time == "early" ~ pick_date,
pick_time == "late" ~ pick_date + days(1),
TRUE ~ pick_date)
) %>%
mutate(new_pick_date = make_datetime(year(temp_pick_date), month(temp_pick_date), day(temp_pick_date), hour(new_pick_time), minute(new_pick_time), second(new_pick_time))) %>%
select(-new_pick_time, -temp_pick_date)
这个returns
pick_date ship_date pick_time new_pick_date
1 2017-04-01 00:51:00 2017-04-05 06:55:00 early 2017-04-01 03:00:00
2 2017-04-02 08:53:00 2017-04-09 12:11:00 okay 2017-04-02 08:53:00
3 2017-04-15 16:12:00 2017-04-30 13:11:00 late 2017-04-16 03:00:00
4 2017-04-23 02:04:00 2017-05-02 15:16:00 early 2017-04-23 03:00:00
5 2017-04-30 20:08:00 2017-05-05 09:57:00 late 2017-05-01 03:00:00