【发布时间】:2016-03-17 23:10:11
【问题描述】:
我一直在尝试寻找一个优雅的 data.table 解决方案(但如果有更好的解决方案,我会采用另一个)关于如何组合处理 (1) 嵌套间隔、(2) 具有不同优先级的间隔的日期间隔, (3) 有间隙的区间(参见示例输入对象)。我设法通过 foverlaps 和 shift 找到了一个几乎成功的解决方案。我希望避免 for/while 循环或笛卡尔积,它们都是低效且不优雅的,但肯定会起作用。我希望有更好的东西,因为这是我必须处理的常见数据问题。根据要求,我将展示我几乎有效的解决方案,如果这有用的话。
require(data.table)
# my data looks somewhat like this...
input <- data.table(
person_ID = c(rep(98723, 4), rep(8534, 2), 11223, rep(22446, 2)),
team = c(rep("A", 4), rep("B", 2), "A", "B", "A"),
start_date = as.Date(c("2009-10-1", "2011-11-21", "2012-1-23", "2013-3-2",
"2009-11-14", "2010-1-1", "2012-1-2", "2011-2-2", "2012-4-3")),
end_date = as.Date(c("2010-5-23", NA, "2015-01-02", "2013-3-2", "2009-12-31",
"2010-3-1", "2015-03-22", "2016-1-2", "2014-9-30")))
team_priority <- data.table(team = c("A", "B"), priority = c(1, 2))
input[team_priority, priority := i.priority, on = "team"]
输入
person_ID team start_date end_date priority
1: 98723 A 2009-10-01 2010-05-23 1
2: 98723 A 2011-11-21 <NA> 1
3: 98723 A 2012-01-23 2015-01-02 1
4: 98723 A 2013-03-02 2013-03-02 1
5: 8534 B 2009-11-14 2009-12-31 2
6: 8534 B 2010-01-01 2010-03-01 2
7: 11223 A 2012-01-02 2015-03-22 1
8: 22446 B 2011-02-02 2016-01-02 2
9: 22446 A 2012-04-03 2014-09-30 1
# problem 1: gap in teams prevents simple min/max solution (see person_ID == 98723)
# problem 2: teams have priorities, so if team B is inside of time interval assigned to time A,
# then we need the records to reflect the following:
# team B -> team A -> team B based on when teams A & B start/stop (see person_ID == 22446)
# NOTE: problem 1 and 2 can be combined (I am trying to fix bad data entry)
# I have to assign priorities based on team involvement (A > B > C, etc)
output <- data.table(
person_ID = c(rep(98723, 4), rep(8534, 2), 11223, rep(22446, 3)),
team = c(rep("A", 4), rep("B", 2), "A", "B", "A", "B"),
start_date = as.Date(c("2009-10-1", "2011-11-21", "2012-1-23", "2013-3-2",
"2009-11-14", "2010-1-1", "2012-1-2", "2011-2-2", "2012-4-3", "2014-10-1")),
end_date = as.Date(c("2010-5-23", NA, "2015-01-02", "2013-3-2", "2009-12-31",
"2010-3-1", "2015-03-22", "2012-4-2", "2014-9-30", "2016-1-2")),
group_id = c(1, rep(2, 3), rep(4, 2), 5, 6, 7, 8))
输出
person_ID team start_date end_date group_id
1: 98723 A 2009-10-01 2010-05-23 1
2: 98723 A 2011-11-21 <NA> 2
3: 98723 A 2012-01-23 2015-01-02 2
4: 98723 A 2013-03-02 2013-03-02 2
5: 8534 B 2009-11-14 2009-12-31 4
6: 8534 B 2010-01-01 2010-03-01 4
7: 11223 A 2012-01-02 2015-03-22 5
8: 22446 B 2011-02-02 2012-04-02 6
9: 22446 A 2012-04-03 2014-09-30 7
10: 22446 B 2014-10-01 2016-01-02 8
简单的 MIN/MAX 解决方案行不通!我不反对单独处理嵌套间隔(请参阅 person_id == 22446),但这确实是我在同时实现所有其他目标的同时无法弄清楚的部分。
【问题讨论】:
标签: r data.table