【发布时间】:2011-06-21 13:07:04
【问题描述】:
我有一个包含 ID、开始日期和结束日期的数据框。我的数据按 ID、开始、结束(按此顺序)排序。
现在我希望将所有具有相同 ID 且具有重叠时间跨度(或开始日期正好在另一行的结束日期之后的第二天)的行合并在一起。
合并它们意味着它们最终排成一行,具有相同的 ID、最小值(开始日期)和最大值(结束日期)(我希望你明白我的意思)。
我为此编写了一个函数(它尚未经过全面测试,但目前看起来还不错)。问题是,由于我的数据框有近 100.000 个观测值,因此该函数非常慢。
您能帮我提高效率方面的功能吗?
这里是函数
smoothingEpisodes <- function (theData) {
theOutput <- data.frame()
curId <- theData[1, "ID"]
curStart <- theData[1, "START"]
curEnd <- theData[1, "END"]
for(i in 2:nrow(theData)) {
nextId <- theData[i, "ID"]
nextStart <- theData[i, "START"]
nextEnd <- theData[i, "END"]
if (curId != nextId | (curEnd + 1) < nextStart) {
theOutput <- rbind(theOutput, data.frame("ID" = curId, "START" = curStart, "END" = curEnd))
curId <- nextId
curStart <- nextStart
curEnd <- nextEnd
} else {
curEnd <- max(curEnd, nextEnd, na.rm = TRUE)
}
}
theOutput <- rbind(theOutput, data.frame("ID" = curId, "START" = curStart, "END" = curEnd))
theOutput
}
谢谢!
[编辑]
测试数据:
ID START END
1 1 2000-01-01 2000-03-31
2 1 2000-04-01 2000-05-31
3 1 2000-04-15 2000-07-31
4 1 2000-09-01 2000-10-31
5 2 2000-01-15 2000-03-31
6 2 2000-02-01 2000-03-15
7 2 2000-04-01 2000-04-15
8 3 2000-06-01 2000-06-15
9 3 2000-07-01 2000-07-15
(START 和 END 的数据类型为“日期”,ID 为数字)
数据的输入:
structure(list(ID = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L), START = structure(c(10957,
11048, 11062, 11201, 10971, 10988, 11048, 11109, 11139), class = "Date"),
END = structure(c(11047, 11108, 11169, 11261, 11047, 11031,
11062, 11123, 11153), class = "Date")), .Names = c("ID",
"START", "END"), class = "data.frame", row.names = c(NA, 9L))
【问题讨论】:
-
dput()的输出更有用,因为我们需要对象是日期。
标签: function r datetime performance