我有两个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")))
答案 0 :(得分:3)
您可以通过合并有效地解决此问题。
首先在dataset.old中创建所需的rownumber变量。然后将dataset.new
与dataset.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.date
或is.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