У меня есть фрейм данных d1
с наблюдениями в определенных местах l
и временами t
.
> head(d1, 3)
id l p t X
1 1 258 2016 2016-01-05 -1.158644
2 5 261 2016 2016-01-14 1.604873
3 2 261 2016 2016-01-20 -1.102002
В другом фрейме данных p2
У меня есть временные интервалы t1:t2
для местоположений l
, и я хочу проверять строку за строкой, если кортежи d1
соответствуют местоположению и интервалу временикортежи p2
.
> head(p2, 3)
l p t1 t2
1 261 2016 2016-01-11 2016-01-25
2 261 2017 2017-02-27 2017-03-13
3 261 2017 2017-03-01 2017-03-15
В положительном случае фиктивной переменной d1$match
должно быть присвоено значение 1, в отрицательном случае 0:
# [1] 0 1 1 ...
Моя попыткапока что, во-первых, нужно свернуть l
и p
обоих фреймов данных в строки и сравнить их, а во-вторых, проверить, лежит ли t
в t1:t2
.
Однако код, который я придумал, немного неуклюжий, и он работает более или менее, только если периоды не пересекаются, как в p1
.Более того, предупреждения также выдаются из-за проблем с классами "Date"
.
> p1
l p t1 t2
1 261 2016 2016-01-11 2016-01-25
2 261 2017 2017-02-27 2017-03-13
4 258 2018 2018-01-09 2018-01-23
p <- p1
p.strg <- sapply(1:nrow(p), function(x) {
do.call(paste, c(p[x, c("l", "p")], sep = "|"))
})
sapply(1:nrow(d1), function(x) {
strg <- do.call(paste, c(d1[x, c("l", "p")], sep = "|"))
t.d <- d1[x, "t"]
t.p <- p[which(p.strg %in% strg), c("t1", "t2")]
return(as.integer(any(p.strg %in% strg) & t.d >= t.p[1] &
t.d <= t.p[2]))
})
# [1] 0 1 1 0 0 0 1 1 0 0 0 1 0 0 0
# There were 30 warnings (use warnings() to see them)
# warnings()
# Warning messages:
# 1: In FUN(X[[i]], ...) :
# Incompatible methods ("Ops.Date", "Ops.data.frame") for ">="
# ...
Если периоды перекрываются, как в p2
,
p <- p2
p.strg <- sapply(1:nrow(p), function(x) {
do.call(paste, c(p[x, c("l", "p")], sep = "|"))
})
sapply(1:nrow(d1), function(x) {
strg <- do.call(paste, c(d1[x, c("l", "p")], sep = "|"))
t.d <- d1[x, "t"]
t.p <- p[which(p.strg %in% strg), c("t1", "t2")]
return(as.integer(any(p.strg %in% strg) & t.d >= t.p[1] &
t.d <= t.p[2]))
})
, он выиграл 'вообще не работает:
Error in FUN(X[[i]], ...) :
(list) object cannot be coerced to type 'double'
In addition: There were 13 warnings (use warnings() to see them)
Я думаю, что я немного растерялся.Что было бы лучше для решения этой проблемы в базе R ?
Примечание: Мои исходные данные несколько более обширны (d1: 20000 x 11, p2:1700 x 8), поэтому мне нужно эффективное решение.
Данные:
d1 <- structure(list(id = c(1L, 5L, 2L, 3L, 1L, 3L, 4L, 5L, 2L, 3L,
5L, 1L, 2L, 4L, 4L), l = c(258, 261, 261, 260, 258, 260, 261,
261, 259, 260, 261, 258, 259, 261, 261), p = c(2016, 2016, 2016,
2016, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2018, 2018, 2018,
2018), t = structure(c(16805, 16814, 16820, 16924, 17193, 17211,
17227, 17229, 17348, 17481, 17517, 17543, 17554, 17787, 17887
), class = "Date"), X = c(-1.15864442153663, 1.60487335898257,
-1.10200153102672, -0.823719007033067, 1.20944271845298, 0.790388149166713,
-1.0996495357495, -0.421449225963478, -0.243567712934607, -0.337415580767635,
-1.64590022554026, 2.11206142393207, -0.950235138478342, -2.08164602167738,
-1.88576409729638), match = c(0L, 1L, 1L, 0L, 0L, 0L, 1L, 1L,
0L, 0L, 0L, 1L, 0L, 0L, 0L)), row.names = c(NA, -15L), class = "data.frame")
p1 <- structure(list(l = c(261, 261, 258), p = c(2016, 2017, 2018),
t1 = structure(c(16811, 17224, 17540), class = "Date"), t2 = structure(c(16825,
17238, 17554), class = "Date")), row.names = c(1L, 2L, 4L
), class = "data.frame")
p2 <- structure(list(l = c(261, 261, 261, 258, 259, 261), p = c(2016,
2017, 2017, 2018, 2018, 2018), t1 = structure(c(16811, 17224,
17226, 17540, 17551, 17884), class = "Date"), t2 = structure(c(16825,
17238, 17240, 17554, 17565, 17898), class = "Date")), row.names = c(NA,
-6L), class = "data.frame")