Tenir compte du data.table des événements suivants:Trouver les matchs les plus proches de chaque ligne et somme sur la base d'une condition
library(data.table)
breaks <- data.table(id = 1:8,
Channel = c("NP1", "NP1", "NP2", "NP2", "NP3", "NP3", "AT4", "AT4"),
Time = c(1000, 1100, 975, 1075, 1010, 1080, 1000, 1050),
Day = c(1, 1, 1, 1, 1, 1, 1, 1),
ZA = c(15, 12, 4, 2, 1, 2, 23, 18),
stringsAsFactors = F)
breaks
id Channel Time Day ZA
1: 1 NP1 1000 1 15
2: 2 NP1 1100 1 12
3: 3 NP2 975 1 4
4: 4 NP2 1075 1 2
5: 5 NP3 1010 1 1
6: 6 NP3 1080 1 2
7: 7 AT4 1000 1 23
8: 8 AT4 1050 1 18
Pour chaque événement unique dans les pauses, je veux trouver les événements les plus proches dans tous les autres canaux en utilisant la Time
où Day == Day
puis additionner les valeurs de ZA pour ces événements.
Ceci est le résultat que je veux atteindre:
id Channel Time Day ZA Sum
1: 1 NP1 1000 1 15 28
2: 2 NP1 1100 1 12 22
3: 3 NP2 975 1 4 39
4: 4 NP2 1075 1 2 32
5: 5 NP3 1010 1 1 42
6: 6 NP3 1080 1 2 32
7: 7 AT4 1000 1 23 20
8: 8 AT4 1050 1 18 19
Donc, pour la première ligne du canal est NP1. Les événements se ferme tous les autres canaux Time = 1000
sont les lignes 3, 5 et 7. 4+1+23 = 28
J'ai eu que cela fonctionne en utilisant data.table avec le code suivant:
breaks[breaks[, c("Day", "Time", "Channel", "ZA")], on = "Day", allow.cartesian = TRUE][
Channel != i.Channel][
order(id)][
, delta := abs(Time - i.Time)][
, .SD[delta == min(delta)], by = .(Channel, Time, Day, i.Channel)][
, unique(.SD, by = c("id", "i.Channel"))][
, .(Sum = sum(i.ZA)), by = .(id, Channel, Time, Day, ZA)]
Cependant, cela crée un ensemble de données avec 64 lignes dans la première étape et je voudrais le faire avec un ensemble de données de plus d'un million de lignes.
Quelqu'un peut-il m'aider à trouver un moyen plus efficace de le faire?
Edit:
J'ai essayé les solutions de G. Grothendieck (sqldf), Eddi (data.table) et MarkusN (dplyr) une fois sur l'ensemble des données de 1,4 millions de lignes avec 39 canaux différents. L'ensemble de données était en mémoire.
sqldf: 54 minutes
data.table: 11 hours
dplyr: 29 hours
Ne résout pas le problème d'OP - vous faites exactement la même chose qu'ils ont fait. – eddi
Je pense que c'est une réponse valable à la question et il est utile de comparer plusieurs approches. Il donne la même réponse que celle de la question. –
@ G.Grothendieck Non, ce n'est certainement pas le cas. La préoccupation d'OP est de se joindre à lui-même sur des données d'un million de lignes, et cette réponse ne touche pas à cela. – eddi