DF <- data.frame(measurement_date = seq(as.POSIXct("2011-01-17 13:00:00"),
as.POSIXct("2011-01-17 13:56:00"),
by = "mins")[seq(1, 57, by = 4)][-6],
value = c(5,5,7,8,4,6,5,6,9,8,6,6,4,6))
full <- data.frame(measurement_date = seq(as.POSIXct("2011-01-17 13:00:00"),
by = "mins", length = 60),
value = rep(NA, 60))
Можно использовать два подхода, первый через merge
:
> v1 <- merge(full, DF, by.x = 1, by.y = 1, all = TRUE)[, c(1,3)]
> names(v1)[2] <- "value" ## I only reset this to pass all.equal later
> head(v1)
measurement_date value
1 2011-01-17 13:00:00 5
2 2011-01-17 13:01:00 NA
3 2011-01-17 13:02:00 NA
4 2011-01-17 13:03:00 NA
5 2011-01-17 13:04:00 5
6 2011-01-17 13:05:00 NA
Вторая - через переменную индикатора, полученную с использованием %in%
:
> want <- full$measurement_date %in% DF$measurement_date
> full[want, "value"] <- DF[, "value"]
> head(full)
measurement_date value
1 2011-01-17 13:00:00 5
2 2011-01-17 13:01:00 NA
3 2011-01-17 13:02:00 NA
4 2011-01-17 13:03:00 NA
5 2011-01-17 13:04:00 5
6 2011-01-17 13:05:00 NA
> all.equal(v1, full)
[1] TRUE
Версия слияния настоятельно предпочтительна, но требует небольшой работы. Решение %in%
работает здесь только потому, что данные располагаются во временном порядке как в DF
, так и full
, следовательно, мое ранее "предпочтительное" Тем не менее, легко получить / обеспечить два объекта в определенном временном порядке, поэтому оба подхода требуют небольшой утонченности для работы. Мы можем изменить подход %in%
, чтобы привести обе переменные в порядок (начиная заново с full
):
full2 <- data.frame(measurement_date = seq(as.POSIXct("2011-01-17 13:00:00"),
by = "mins", length = 60),
value = rep(NA, 60))
full2 <- full2[order(full2[,1]), ] ## get full2 in order
DF2 <- DF[order(DF[,1]), ] ## get DF in order
want <- full$measurement_date %in% DF$measurement_date
full2[want, "value"] <- DF2[, "value"]
> all.equal(full, full2)
[1] TRUE
> all.equal(full2, v1)
[1] TRUE
>