Если я правильно понимаю для каждой поездки и остановки, вы хотите, чтобы в строке была максимальная временная метка, для которой скорость равна нулю, или если такой строки нет, тогда в строке максимальной временной отметки для строк, имеющих скорость, отличную от 0, в этой группе.Далее мы сделаем альтернативное предположение, что в случае отсутствия скоростных рядов в группе просто используйте NA.После этого мы обсуждаем запрос EXCEPT в вопросе.
В первом случае, приведенном выше, группировка по поездке, остановка и скорость == 0. Это даст 2 строки за поездку и остановку, если есть как 0, так и не-0 скоростей и выдаст отключение на 1 строку и остановку, если есть только скорости, отличные от 0.В каждой группе мы берем строку для скорости == 0 является наибольшим.Так как TRUE> FALSE, тогда, если есть две строки, она будет принимать строку, для которой скорость равна 0, а в противном случае она будет принимать одну ненулевую строку скорости.
sqldf("SELECT trip_id, stop_id, timestamp, MAX(speed0) speed0
FROM
(SELECT trip_id, stop_id, MAX(timestamp) timestamp, speed == 0 speed0
FROM df
GROUP BY 1, 2, 4)
GROUP BY 1, 2")
, давая:
trip_id stop_id timestamp speed0
1 1 1 3 1
2 1 2 104 0
3 1 3 202 1
1 в строке 1 для speed0 означает, что для этой группы была найдена строка скорости == 0, поэтому для этой группы использовалась максимальная временная метка, равная только скорости == 0 строк.Аналогично, в строке 2 значение 0 для speed0 означает, что для этой группы не было найдено строки speed == 0, поэтому она использовала максимальную временную метку для строк, отличных от 0 в этой группе.
Если вы не хотите4-й столбец просто добавьте [-4] после окончания).
Альтернативная интерпретация
Если вы хотели, чтобы в этих строках был NA, для которого нет скорости == 0, тогда просто замените первыйстрока в sql выше, как показано здесь:
sqldf("SELECT trip_id, stop_id, NULLIF(MAX(speed0) * timestamp, 0) timestamp
FROM
(SELECT trip_id, stop_id, MAX(timestamp) timestamp, speed == 0 speed0
FROM df
GROUP BY 1, 2, 4)
GROUP BY 1, 2")
, давая:
trip_id stop_id timestamp
1 1 1 3
2 1 2 NA
3 1 3 202
Еще один способ сделать это с левым соединением, дающим тот же результат:
sqldf("WITH a(trip_id, stop_id) AS (
SELECT distinct trip_id, stop_id
FROM df),
b(trip_id, stop_id, timestamp) AS (
SELECT trip_id, stop_id, MAX(timestamp) timestamp
FROM df
WHERE speed == 0
GROUP BY 1, 2)
SELECT *
FROM a LEFT JOIN b
USING (trip_id, stop_id)")
ИСКЛЮЧИТЬ против НЕ СУЩЕСТВУЕТ
Что касается последней строки кода в вопросе, касающемся ИСКЛЮЧЕНИЯ, это будет сделано с использованием следующего коррелированного подзапроса, показанного с НЕ СУЩЕСТВУЮЩИМ, как это:
sqldf("SELECT a.trip_id, a.stop_id, MIN(a.timestamp) timestamp
FROM df a
WHERE NOT EXISTS (
SELECT *
FROM df b
WHERE speed == 0 AND a.trip_id = b.trip_id AND a.stop_id = b.stop_id)
GROUP by 1, 2")
давая:
trip_id stop_id timestamp
1 1 2 101
Примечание
Мы предполагаем, что этот ввод показан в воспроизводимой форме:
Lines <- "
trip_id stop_id speed timestamp
1 1 1 5 1
2 1 1 0 2
3 1 1 0 3
4 1 1 5 4
5 1 2 2 101
6 1 2 2 102
7 1 2 2 103
8 1 2 2 104
9 1 3 4 201
10 1 3 0 202"
df <- read.table(text = Lines)