查找R中特定日期之前的最新数据

时间:2016-09-02 15:08:36

标签: r dataframe

我有两个data.frames(称为 dataset.new dataset.old ),它们都包含有关某些人的信息。这些人都有一个识别号码(我们称之为“个人”的变量),它出现在两个data.frames中,每个帧都有关于何时收集数据的信息,存储在我们可以称之为“some.date”的列中。 ”

这两个data.frames(dataset.old)中的第二个包含个体的历史数据,即在其他时间测量的一些其他变量的值,因此每个个体在dataset.old中出现多次。

我希望做的是以下内容。对于dataset.new中的每个人,找到dataset.old中最新但仍然比dataset.new中的观察值更早的行。对于在dataset.old中没有此类日期的个人,我希望它返回NA。

这可能是最简单的一些示例数据,如下所示。

dataset.new 
 individual  some.date
1         1 2016-05-01
2         2 2016-01-28
3         7 2016-03-03

dataset.old
   individual  some.date
1           1 2016-01-12
2           1 2015-12-30
3           1 2016-04-27
4           1 2016-05-02
5           2 2015-11-15
6           2 2012-01-27
7           2 2016-02-06
8           3 2016-04-30
9           3 2016-01-27
10          4 2016-03-01
11          4 2011-01-16

在这个例子中,我正在寻找一种获得以下输出的方法:

individual row.nr
1          1      3
2          2      5
3          7     NA

因为这些行对应于dataset.old中的最新数据,该数据仍然比dataset.new中的数据旧。

我有一个解决问题的代码,但对于我想到的数据来说太慢了(数据集中有超过20 000行。在dataset.old中有很多,甚至更多)。我的解决方案基本上是对所有个体的循环,在每个阶段对数据进行子集化。

find.previous <- function(dataset.old, individual, some.new.date){
  subsetted.dataset <- dataset.old[dataset.old[, "individual"] == individual, ] # We only look at the individual in question.
  subsetted.dataset <- subsetted.dataset[subsetted.dataset[, "some.date"] < some.new.date, ]# Here we get all the rows that have data that are measured BEFORE timepoint.
  row.index <- which.min(some.new.date - subsetted.dataset[, "some.date"]) # This can be done, since we have already made sure that fromdatum < timepoint.
  ifelse(length(row.index)!= 0, as.integer(rownames(subsetted.dataset[row.index,])), NA) # Then we output the row that had that information.
}

output <- matrix(ncol=2, nrow=0)
for(i in 1:nrow(dataset.new)){
  output <- rbind(output, cbind(dataset.new[, "individual"][i], find.previous(dataset.old, dataset.new[, "individual"][i], dataset.new[, "some.date"][i])))
}
colnames(output) <- c("individual", "row.nr")
output

如何解决这个问题的任何帮助将不胜感激。我已尝试使用我的Google技能以及阅读此处stackoverflow上的其他帖子,但没有成功。

可以通过复制以下代码行来复制示例数据:

dataset.new <- data.frame(individual=c(1, 2, 7), some.date=as.Date(c("2016-05-01", "2016-01-28", "2016-03-03")))
dataset.old <- data.frame(individual=c(1,1,1,1,2,2,2,3,3,4,4), some.date=as.Date(c("2016-01-12", "2015-12-30", "2016-04-27", "2016-05-02", "2015-11-15", "2012-01-27", "2016-02-06", "2016-04-30", "2016-01-27", "2016-03-01", "2011-01-16")))

2 个答案:

答案 0 :(得分:3)

您可以通过合并有效地解决此问题。

首先在dataset.old中创建所需的rownumber变量。然后将dataset.newdataset.old合并到个人(左连接或merge(lhs, rhs, all.x = TRUE))上。这可以帮到你:

dataset.old
   individual   new.date    old.date    old.rownumber
1           1   2016-05-01  2016-01-12              1
2           1   2016-05-01  2015-12-30              2
3           1   2016-05-01  2016-04-27              3
4           1   2016-05-01  2016-05-02              4
5           2   2016-01-28  2015-11-15              5
6           2   2016-01-28  2012-01-27              6
7           2   2016-01-28  2016-02-06              7 
8           7   2016-03-03          NA             NA

子集为new.date > old.dateis.na(old.date)

dataset.old
   individual   new.date    old.date    old.rownumber
1           1   2016-05-01  2016-01-12              1
2           1   2016-05-01  2015-12-30              2
3           1   2016-05-01  2016-04-27              3
5           2   2016-01-28  2015-11-15              5
6           2   2016-01-28  2012-01-27              6
8           7   2016-03-03          NA             NA

old.date == max(old.date)分组的is.na(old.date)individual子集。

dataset.old
   individual   new.date    old.date    old.rownumber
3           1   2016-05-01  2016-04-27              3
6           2   2016-01-28  2012-01-27              5
8           7   2016-03-03          NA             NA

编辑: 我偏向data.table。代码看起来像:

dataset.old[, old.rownumber := 1:.N]

setnames(dataset.old, "some.date", "old.date")
setnames(dataset.new, "some.date", "new.date")

dataset.merge <- merge(dataset.old, dataset.new, by = "individual", all.x = TRUE)

dataset.merge <- dataset.merge[, new.date > old.date]
dataset.merge[old.date == max(old.date) | is.na(old.date), by = individual]

答案 1 :(得分:1)

我们可以通过找到最小平方根来跳过completeWorkItem搜索。对我们来说,负值将被强制丢失:

NA