我有两个基于日期时间字段的表。为了重新创建场景,让我们以商业与销售为例。我们想知道哪个销售与哪个广告有关。
销售只能标记到最后一个广告,并且只有在广告之后才可以标记。
此外,如果在多个广告之后发生了销售,我们只能将销售标记为最后一个广告;之前的广告素材中的连接无效。
我无法获得最后一部分。如果在多个广告之后进行销售,则所有此类广告都将与该销售合并;我不要在我的示例中,发生在“ 2017-01-01 02:05:00”的销售应与在“ 2017-01-01 02:00:00”播放的广告一起,而不是先前的广告。
library(lubridate)
library(data.table)
ts <- seq(as.POSIXct("2017-01-01", tz = "UTC"),
as.POSIXct("2017-01-02", tz = "UTC"),
by = "30 min")
commercial <-
data.table(
c_row_number = 1:10,
c_time = ts[1:10],
c_time_roll = ts[1:10]
)
sale <-
data.table(
s_row_number = 1:4,
s_time = ts[5:8] + minutes(5),
s_time_roll = ts[5:8] + minutes(5)
)
setkey(commercial, c_time_roll)
setkey(sale, s_time_roll)
tbl_joined <- sale[commercial, roll = -Inf] # , mult = 'last']
任何想法我们如何获得c_row_number为1、2、3和4的NA。谢谢。
答案 0 :(得分:1)
无法直接执行此操作-x[i]
使用i
在x
中查找行。 mult
用于反向操作-当x
中的多行与i
中的单行匹配时。这里,i
中的多行与x
中的单行匹配。
那么,最好的选择是对结果表进行后联接。例如,要删除这些行,可以使用unique
:
unique(sale[commercial, roll = -Inf], by = 's_row_number', fromLast = TRUE)
# s_row_number s_time s_time_roll c_row_number
# 1: 1 2017-01-01 02:05:00 2017-01-01 02:00:00 5
# 2: 2 2017-01-01 02:35:00 2017-01-01 02:30:00 6
# 3: 3 2017-01-01 03:05:00 2017-01-01 03:00:00 7
# 4: 4 2017-01-01 03:35:00 2017-01-01 03:30:00 8
# 5: NA <NA> 2017-01-01 04:30:00 10
# c_time
# 1: 2017-01-01 02:00:00
# 2: 2017-01-01 02:30:00
# 3: 2017-01-01 03:00:00
# 4: 2017-01-01 03:30:00
# 5: 2017-01-01 04:30:00
我怀疑您是为此任务而创建{s,c}_row_number
的;为此,如果没有这些列,您可以这样做:
sale[commercial, roll = -Inf][order(-c_time)][rowid(s_time) == 1L]
我们用c_time
进行反向排序,以确保rowid
获得最新的值。
请注意,在两种情况下,is.na(s_time)
行之一都已删除。
希望这能使您朝正确的方向前进。
答案 1 :(得分:1)
如果对您的商业时间进行了排序, 或者您可以对它们进行排序 那么您可以将非等额联接与时间偏移的帮助器列配合使用:
library(lubridate)
library(data.table)
ts <- seq(as.POSIXct("2017-01-01", tz = "UTC"),
as.POSIXct("2017-01-02", tz = "UTC"),
by = "30 min")
commercial <-
data.table(
c_row_number = 1:10,
c_time = ts[1:10],
c_next_time = shift(ts[1:10], type = "lead", fill = max(ts))
)
sale <-
data.table(
s_row_number = 1:4,
s_time = ts[5:8] + minutes(5),
s_time_join = ts[5:8] + minutes(5)
)
tbl_joined <- sale[commercial, on = .(s_time_join >= c_time, s_time_join < c_next_time)]
如果要使用this idiom:
commercial[, s_time := sale[.SD,
.(s_time),
on = .(s_time_join >= c_time, s_time_join < c_next_time)]]
print(commercial)
c_row_number c_time c_next_time s_time
1: 1 2017-01-01 00:00:00 2017-01-01 00:30:00 <NA>
2: 2 2017-01-01 00:30:00 2017-01-01 01:00:00 <NA>
3: 3 2017-01-01 01:00:00 2017-01-01 01:30:00 <NA>
4: 4 2017-01-01 01:30:00 2017-01-01 02:00:00 <NA>
5: 5 2017-01-01 02:00:00 2017-01-01 02:30:00 2017-01-01 02:05:00
6: 6 2017-01-01 02:30:00 2017-01-01 03:00:00 2017-01-01 02:35:00
7: 7 2017-01-01 03:00:00 2017-01-01 03:30:00 2017-01-01 03:05:00
8: 8 2017-01-01 03:30:00 2017-01-01 04:00:00 2017-01-01 03:35:00
9: 9 2017-01-01 04:00:00 2017-01-01 04:30:00 <NA>
10: 10 2017-01-01 04:30:00 2017-01-02 00:00:00 <NA>