我有以下数据框:
Date.POSIXct Date WeekDay DayCategory Hour Holidays value
1 2018-05-01 00:00:00 2018-05-01 MA MA-MI-JU 0 0 30
2 2018-05-01 01:00:00 2018-05-01 MA MA-MI-JU 1 0 80
3 2018-05-01 02:00:00 2018-05-01 MA MA-MI-JU 2 0 42
4 2018-05-01 03:00:00 2018-05-01 MA MA-MI-JU 3 0 90
5 2018-05-01 04:00:00 2018-05-01 MA MA-MI-JU 4 0 95
6 2018-05-01 05:00:00 2018-05-01 MA MA-MI-JU 5 0 5
DayCategory按以下方式分组星期几:星期一转到LU
DayCategory。星期二,星期三和星期四转到MA-MI-JU
DayCategory。
星期五分别到VI
,星期六到SA
,星期日到DO
分类。
我希望在前一天(value
)找到同一hour
Date
DayCategory
Holidays
,而holiday
仍在DayCategory
内相同的组(例如,如果一个实例有PreviousDaySameDayCategory
0但前一天有相同的Date
有1,我们应该看看前一个等等。)
作为中间步骤并且为了理解该过程,我想添加一个列DayCategory
,其中前一天的date
与相应的行具有相同的library(lubridate)
Date.POSIXct <- seq(as.POSIXct("2018-05-01"), as.POSIXct("2018-05-31"), "hour")
mydf <- as.data.frame(Date.POSIXct)
mydf$Date <- as.Date(substr(as.character(mydf$Date.POSIXct),1,10))
mydf$WeekDay <- substr(toupper((weekdays(mydf$Date))),1,2)
mydf$DayCategory <-as.factor(ifelse(mydf$WeekDay == "MA" | mydf$WeekDay == "MI" | mydf$WeekDay == "JU",
"MA-MI-JU", mydf$WeekDay))
mydf$Hour <- hour(mydf$Date.POSIXct)
mydf$Holidays <- c(rep(0, 24*7),rep(1, 24*7), rep(0, 24*16+1))
set.seed(123)
mydf$myvalue <- sample.int(101,size=nrow(mydf),replace=TRUE)
。有时它将是相同的 a <- rep(NA, 24)
b <- mydf$value[1:24]
c <- mydf$value[25:48]
d <- rep(NA, 24)
e <- rep(NA,24)
f <- rep(NA,24)
g <- rep(NA,24)
h <- rep(NA,24)
i <- mydf$value[169:192]
solution <- c(a,b,c,d,e,f,g,h,i)
solution
减去七天(&#34; LU&#34;,&#34; VI&#34;,&#34; SA&#34;,&#34; DO&# 34;)但其他日子只有一天。
可重复数据:
{{1}}
我已经手动启动了第一天,并提出了解决方案应该如何的向量:
{{1}}
我很感激思维过程中的任何暗示,以相对频率解决我面临的这类问题。
答案 0 :(得分:1)
以下是data.table
解决方案,该解决方案使用“分组shift()
”和多个联接来复制value
hour
的{{1}}。< / p>
用于创建可重现数据的OP代码不能完全重现,因为他使用PreviousDaySameDayCategory
函数返回当前语言环境中的工作日名称(OP似乎是西班牙语)。为了独立于当前的语言环境,我切换到weekdays()
,它返回星期一到星期日的数字1到7。此外,format(Date, "%u")
包中的fct_collapse()
用于将第2,3和4天(周二到周四)折叠为一个因子级别。
forcats
library(data.table)
# note that package lubridate is not required
myDT <- data.table(Date.POSIXct = seq(as.POSIXct("2018-05-01"),
as.POSIXct("2018-05-31"), "hour"))
myDT[, Date := as.Date(Date.POSIXct)]
myDT[, Weekday := format(Date, "%u")]
myDT[, DayCategory := forcats::fct_collapse(Weekday, "234" = c("2", "3", "4"))]
myDT[, hour := hour(Date.POSIXct)]
myDT[, Holidays := c(rep(0, 24 * 7), rep(1, 24 * 7), rep(0, 24 * 16 + 1))]
set.seed(123)
myDT[, myvalue := sample.int(101, size = nrow(mydf), replace = TRUE)]
示例数据集由每小时数据组成,但为了确定我们需要每天工作的PreviousDaySameDayCategory
,因此只需要处理PreviousDaySameDayCategory
,{{1}的唯一值}和Date
。数据按DayCategory
和Holidays
指标进行分组。对于每个组,前一天选择滞后DayCategory
。由于Holidays
操作的结果取决于数据集在移位之前的排序行。
Date
shift()
在第3天和第4天(周三和周四),选择同一周的周二和周三。对于第2天(星期二),如果两周都有相同的假期指标设置,那么前一周的前一周将被选中。如果前一周有不同的假期指标,则选择同一假期的最近一个星期四。这就是为什么,例如2018-05-03在第15行被选中。
tmp <- unique(myDT[order(Date), .(Date, DayCategory, Holidays)])[
, .(Date, PreviousDaySameDayCategory = shift(Date)), by = .(DayCategory, Holidays)][
order(Date)]
tmp
DayCategory Holidays Date PreviousDaySameDayCategory
1: 234 0 2018-05-01 <NA>
2: 234 0 2018-05-02 2018-05-01
3: 234 0 2018-05-03 2018-05-02
4: 5 0 2018-05-04 <NA>
5: 6 0 2018-05-05 <NA>
6: 7 0 2018-05-06 <NA>
7: 1 0 2018-05-07 <NA>
8: 234 1 2018-05-08 <NA>
9: 234 1 2018-05-09 2018-05-08
10: 234 1 2018-05-10 2018-05-09
11: 5 1 2018-05-11 <NA>
12: 6 1 2018-05-12 <NA>
13: 7 1 2018-05-13 <NA>
14: 1 1 2018-05-14 <NA>
15: 234 0 2018-05-15 2018-05-03
16: 234 0 2018-05-16 2018-05-15
17: 234 0 2018-05-17 2018-05-16
18: 5 0 2018-05-18 2018-05-04
19: 6 0 2018-05-19 2018-05-05
20: 7 0 2018-05-20 2018-05-06
21: 1 0 2018-05-21 2018-05-07
22: 234 0 2018-05-22 2018-05-17
23: 234 0 2018-05-23 2018-05-22
24: 234 0 2018-05-24 2018-05-23
25: 5 0 2018-05-25 2018-05-18
26: 6 0 2018-05-26 2018-05-19
27: 7 0 2018-05-27 2018-05-20
28: 1 0 2018-05-28 2018-05-21
29: 234 0 2018-05-29 2018-05-24
30: 234 0 2018-05-30 2018-05-29
31: 234 0 2018-05-31 2018-05-30
DayCategory Holidays Date PreviousDaySameDayCategory
这分两步完成。首先,通过加入匹配的日期表value
,从匹配的PreviousDaySameDayCategory
中选择每小时值:
PreviousDaySameDayCategory
tmp
其次,tmp2 <- myDT[tmp, on = .(Date = PreviousDaySameDayCategory), .(Date = i.Date, hour, myvalue), nomatch = 0L]
tmp2
中的新列 Date hour myvalue
1: 2018-05-02 0 30
2: 2018-05-02 1 80
3: 2018-05-02 2 42
4: 2018-05-02 3 90
5: 2018-05-02 4 95
---
500: 2018-05-31 19 39
501: 2018-05-31 20 1
502: 2018-05-31 21 1
503: 2018-05-31 22 101
504: 2018-05-31 23 11
是由在连接中更新创建的,其中包含来自previousValue
的相应值:
myDT
此处显示结果的前两天:
PreviousDaySameDayCategory
myDT[tmp2, on = .(Date, hour), previousValue := i.myvalue]
结果符合OP的预期
myDT[Date %between% c(as.Date("2018-05-01"), as.Date("2018-05-02"))]
Date.POSIXct Date Weekday DayCategory hour Holidays myvalue previousValue 1: 2018-05-01 00:00:00 2018-05-01 2 234 0 0 30 NA 2: 2018-05-01 01:00:00 2018-05-01 2 234 1 0 80 NA 3: 2018-05-01 02:00:00 2018-05-01 2 234 2 0 42 NA 4: 2018-05-01 03:00:00 2018-05-01 2 234 3 0 90 NA 5: 2018-05-01 04:00:00 2018-05-01 2 234 4 0 95 NA 6: 2018-05-01 05:00:00 2018-05-01 2 234 5 0 5 NA 7: 2018-05-01 06:00:00 2018-05-01 2 234 6 0 54 NA 8: 2018-05-01 07:00:00 2018-05-01 2 234 7 0 91 NA 9: 2018-05-01 08:00:00 2018-05-01 2 234 8 0 56 NA 10: 2018-05-01 09:00:00 2018-05-01 2 234 9 0 47 NA 11: 2018-05-01 10:00:00 2018-05-01 2 234 10 0 97 NA 12: 2018-05-01 11:00:00 2018-05-01 2 234 11 0 46 NA 13: 2018-05-01 12:00:00 2018-05-01 2 234 12 0 69 NA 14: 2018-05-01 13:00:00 2018-05-01 2 234 13 0 58 NA 15: 2018-05-01 14:00:00 2018-05-01 2 234 14 0 11 NA 16: 2018-05-01 15:00:00 2018-05-01 2 234 15 0 91 NA 17: 2018-05-01 16:00:00 2018-05-01 2 234 16 0 25 NA 18: 2018-05-01 17:00:00 2018-05-01 2 234 17 0 5 NA 19: 2018-05-01 18:00:00 2018-05-01 2 234 18 0 34 NA 20: 2018-05-01 19:00:00 2018-05-01 2 234 19 0 97 NA 21: 2018-05-01 20:00:00 2018-05-01 2 234 20 0 90 NA 22: 2018-05-01 21:00:00 2018-05-01 2 234 21 0 70 NA 23: 2018-05-01 22:00:00 2018-05-01 2 234 22 0 65 NA 24: 2018-05-01 23:00:00 2018-05-01 2 234 23 0 101 NA 25: 2018-05-02 00:00:00 2018-05-02 3 234 0 0 67 30 26: 2018-05-02 01:00:00 2018-05-02 3 234 1 0 72 80 27: 2018-05-02 02:00:00 2018-05-02 3 234 2 0 55 42 28: 2018-05-02 03:00:00 2018-05-02 3 234 3 0 61 90 29: 2018-05-02 04:00:00 2018-05-02 3 234 4 0 30 95 30: 2018-05-02 05:00:00 2018-05-02 3 234 5 0 15 5 31: 2018-05-02 06:00:00 2018-05-02 3 234 6 0 98 54 32: 2018-05-02 07:00:00 2018-05-02 3 234 7 0 92 91 33: 2018-05-02 08:00:00 2018-05-02 3 234 8 0 70 56 34: 2018-05-02 09:00:00 2018-05-02 3 234 9 0 81 47 35: 2018-05-02 10:00:00 2018-05-02 3 234 10 0 3 97 36: 2018-05-02 11:00:00 2018-05-02 3 234 11 0 49 46 37: 2018-05-02 12:00:00 2018-05-02 3 234 12 0 77 69 38: 2018-05-02 13:00:00 2018-05-02 3 234 13 0 22 58 39: 2018-05-02 14:00:00 2018-05-02 3 234 14 0 33 11 40: 2018-05-02 15:00:00 2018-05-02 3 234 15 0 24 91 41: 2018-05-02 16:00:00 2018-05-02 3 234 16 0 15 25 42: 2018-05-02 17:00:00 2018-05-02 3 234 17 0 42 5 43: 2018-05-02 18:00:00 2018-05-02 3 234 18 0 42 34 44: 2018-05-02 19:00:00 2018-05-02 3 234 19 0 38 97 45: 2018-05-02 20:00:00 2018-05-02 3 234 20 0 16 90 46: 2018-05-02 21:00:00 2018-05-02 3 234 21 0 15 70 47: 2018-05-02 22:00:00 2018-05-02 3 234 22 0 24 65 48: 2018-05-02 23:00:00 2018-05-02 3 234 23 0 48 101 Date.POSIXct Date Weekday DayCategory hour Holidays myvalue previousValue
答案 1 :(得分:1)
OP也在数据科学部分发布了相同的问题。我在这里包含了相同的解决方案,这可能对其他人有帮助。 它类似于Uwe的解决方案,但改为使用dplyr库。
library(dplyr)
rankedDf <- mydf %>%
group_by(DayCategory, Hour, Holidays) %>%
arrange(Date) %>%
mutate(rowRank = order(Date), previousRowRank = order(Date) - 1) %>%
left_join(., ., by = c("previousRowRank" = "rowRank", "DayCategory", "Hour", "Holidays")) %>%
select(
Date.POSIXct = Date.POSIXct.x,
Date = Date.x,
WeekDay = WeekDay.x,
DayCategory,
Hour,
Holidays,
myvalue = myvalue.x,
PreviousDaySameDayCategory = Date.y,
PreviousValueSameDayCategory = myvalue.y
)
print.data.frame(rankedDf)
P.S。喜欢Uwe改变原始示例代码的方式。