历史项目数据
Posted
技术标签:
【中文标题】历史项目数据【英文标题】:Historising project data 【发布时间】:2022-01-18 21:14:08 【问题描述】:我经常遇到这样的问题,即我有描述状态(在本例中为项目阶段)的确切变化的数据,我想记录这些数据。
这意味着我希望能够在过去的某个时间描述哪个项目处于哪个阶段。
让我们使用这个测试数据:
library(data.table)
library(lubridate)
df = structure(list(Project = c("A", "A", "B", "B", "B", "B", "C",
"C", "C", "D", "D"), Date = structure(c(18659, 18748, 18687,
18718, 18748, 18871, 18718, 18718, 18779, 18659, 18840), class = "Date"),
Phase = c("Init", "P2O", "Init", "P2O", "Build", "Doc", "Init",
"P2O", "Build", "Init", "P2O")), row.names = c(NA, -11L), class = c("data.table",
"data.frame"))
df[, Date:=ceiling_date(as.Date(Date, format="%d.%m.%Y"), "month")]
它们看起来像:
Project Date Phase
Project Date Phase
1: A 2021-03-01 Init
2: A 2021-06-01 P2O
3: B 2021-04-01 Init
4: B 2021-05-01 P2O
5: B 2021-06-01 Build
6: B 2021-10-01 Doc
7: C 2021-05-01 Init
8: C 2021-05-01 P2O
9: C 2021-07-01 Build
10: D 2021-03-01 Init
11: D 2021-09-01 P2O
现在我想创建一个表格,其中每个阶段都有一个列,每个日期有一个行。
我试过了:
> dcast(df, Date~Phase, fun=length)[order(Date)]
Date Build Doc Init P2O
1: 2021-03-01 0 0 2 0
2: 2021-04-01 0 0 1 0
3: 2021-05-01 0 0 1 2
4: 2021-06-01 1 0 0 1
5: 2021-07-01 1 0 0 0
6: 2021-09-01 0 0 0 1
7: 2021-10-01 0 1 0 0
但这是一个大错误。 让我们看看A项目。
Project Date Phase
1: A 2021-03-01 Init
2: A 2021-06-01 P2O
项目 A 于 2021 年 3 月 1 日进入“初始化”阶段,2021 年 6 月 1 日进入“P2O”阶段。在当前的逻辑中,这看起来像:
Date Build Doc Init P2O
1: 2021-03-01 0 0 1 0
4: 2021-06-01 0 0 0 1
但这是错误的。在 3 月和 6 月之间,该项目仍处于 Init 阶段,因此正确的应该是这样的:
Date Build Doc Init P2O
1: 2021-03-01 0 0 1 0
2: 2021-04-01 0 0 1 0
3: 2021-05-01 0 0 1 0
4: 2021-06-01 0 0 0 1
有人知道我该如何解决这个问题吗?
【问题讨论】:
【参考方案1】:也许是这个?
dfwide <- dcast(df, Project + Date ~ Phase, fun = length)
merge(
dfwide,
dfwide[, .(Date = seq(min(Date), max(Date), by = "month")), by = .(Project)],
by = c("Project", "Date"), all = TRUE
)[order(Date),
][, setNames(nafill(.SD, type = "locf"), names(.SD)), by = .(Project)]
# Project Date Build Doc Init P2O
# <char> <Date> <int> <int> <int> <int>
# 1: A 2021-03-01 0 0 1 0
# 2: A 2021-04-01 0 0 1 0
# 3: A 2021-05-01 0 0 1 0
# 4: A 2021-06-01 0 0 0 1
# 5: D 2021-03-01 0 0 1 0
# 6: D 2021-04-01 0 0 1 0
# 7: D 2021-05-01 0 0 1 0
# 8: D 2021-06-01 0 0 1 0
# 9: D 2021-07-01 0 0 1 0
# 10: D 2021-08-01 0 0 1 0
# 11: D 2021-09-01 0 0 0 1
# 12: B 2021-04-01 0 0 1 0
# 13: B 2021-05-01 0 0 0 1
# 14: B 2021-06-01 1 0 0 0
# 15: B 2021-07-01 1 0 0 0
# 16: B 2021-08-01 1 0 0 0
# 17: B 2021-09-01 1 0 0 0
# 18: B 2021-10-01 0 1 0 0
# 19: C 2021-05-01 0 0 1 1
# 20: C 2021-06-01 0 0 1 1
# 21: C 2021-07-01 1 0 0 0
# Project Date Build Doc Init P2O
没有文字 merge
也一样(尽管我们只是使用 data.table
-left-join 代替)
dfwide[
dfwide[, .(Date = unique(c(seq(min(Date), max(Date), by = "month"), max(Date)))), by = .(Project)],
on = .(Project, Date)][order(Date),
][, setNames(nafill(.SD, type = "locf"), names(.SD)), by = .(Project)]
unique(c(..., max(Date)))
的使用是为了确保始终使用/保留最大日期;如果seq(.)
中的任何一个未达到最大日期而未登陆,则可能不包括最大日期。当我们使用merge(.., all=TRUE)
时,这不是问题,因为无论如何它都会被保留,但是使用左连接时,它可能会被省略。 (不过,不在这个数据中。我只是在防守。)
【讨论】:
以上是关于历史项目数据的主要内容,如果未能解决你的问题,请参考以下文章
eclipse项目改为maven项目导致svn无法比较历史数据的解决办法
PythonStock(36)股票系统:解决历史数据问题,使用 ak.stock_zh_a_hist 获得历史相关数据,发现AK又更新到了v1.1.1版本,更新获得历史数据代码。
PythonStock(36)股票系统:解决历史数据问题,使用 ak.stock_zh_a_hist 获得历史相关数据,发现AK又更新到了v1.1.1版本,更新获得历史数据代码。