2016-06-23 1 views
0

Ich habe zwei data.table s mit mehreren Spalten als Schlüssel (sie besteht aus den Spalten record, dstPort, srcPort, proto, dstIP und srcIP). Beide haben das gleiche Format.Subtract-Wert aus Daten mit Schlüsseln durch mehrere Spalten in R

dataset_1:

record dstPort srcPort proto   dstIP   srcIP state  timestamp 
1: state  80 32768 tcp 192.168.101.5 192.168.101.89  syn 1466580661185059 
2: state  80 32768 tcp 192.168.101.5 192.168.101.89 syn_ack 1466520661604781 
3: state  80 32768 tcp 192.168.101.5 192.168.101.89 close 1466532661885439 
4: state  80 55555 tcp 192.168.101.5 192.168.101.89  syn 1466532661885440 

und dataset_2:

record dstPort srcPort proto   dstIP   srcIP   state  timestamp 
1: state  80 32768 tcp 192.168.101.5 192.168.101.89  established 1466537661727619 
2: state  80 32768 tcp 192.168.101.5 192.168.101.89   close 1466532661986891 
3: state  80 44444 tcp 192.168.101.5 192.168.101.89  established 1466537661727619 

Das Folgende ist, was würde ich für jeden Schlüssel in der Datenmenge tun: Ich möchte um die Datensätze (Zeilen) mit demselben Schlüssel zu finden und wo ein bestimmter Status verfügbar ist ble (d.h. Zustand syn in Datensatz1 und established in Datensatz_2). Für diese Datensätze möchte ich die Zeitstempel voneinander subtrahieren. Dh:

Für jeden Schlüssel in dataset_1, das heißt:

state 80 32768 tcp 192.168.101.5 192.168.101.89 für Zustand syn Zeitstempel 1466580661185059

und Key in dataset_2 gibt:

state 80 32768 tcp 192.168.101.5 192.168.101.89 für Zustand established gibt Zeitstempel 1466537661727619

Nach dem Subtrahieren von Zeitstempeln: 146658 0661185059-1466537661727619 = 42999457440

Es könnte sein, dass es in Datensatz_2 keinen Datensatz für einen Schlüssel gibt. Aus diesem Grund funktioniert die Sortierung nicht (darauf basieren alle meine Versuche). Ein exemplarischer Versuch ist (nach ihnen Art, welche nicht mehr möglich ist):

dt_state1 <- subset(dt, state == 'established') 
dt_state2 <- subset(dt, state == 'syn') 
dt_delta_test <- data.table(x=(dt_state1$timestamp/1000)- (dt_state2$timestamp/1000),'timestamp'= dt_state1$timestamp-min(dt_state1$timestamp)) 

Update 1: @lmo:

F1_in = as.data.table(read.csv(file=Filename, header=TRUE, sep=",")) 
keys=c("record","dstPort","srcPort","dstIP","srcIP") 
state1 = 'syn' 
state2 = 'established' 
dt_state1 <- subset(F1_in, state == state2) 
setkey(dt_state1, keys) 
Error in setkeyv(x, cols, verbose = verbose, physical = physical) : some columns are not in the data.table: keys 
dt_state2 <- subset(F1_in, state == state1) 
setkey(dt_state2, keys) 
Error in setkeyv(x, cols, verbose = verbose, physical = physical) : some columns are not in the data.table: keys 
dt_state1[dt_state2, timestamp - i.timestamp] 
Error in `[.data.table`(dt_state1, dt_state2, timestamp - i.timestamp) : 
    When i is a data.table (or character vector), x must be keyed (i.e. sorted, and, marked as sorted) so data.table knows which columns to join to and take advantage of x being sorted. Call setkey(x,...) first, see ?setkey. 

Ich weiß nicht, warum dieser Fehler auftritt. .

@ toni057 Ihre Lösung ändert nichts für mich (ich musste einige Änderungen vornehmen, weil es einige Fehler verursachte). Ich habe den folgenden Code versucht:

F1_in = as.data.table(read.csv(file=Filename, header=TRUE, sep=",")) 
keys=c("record","dstPort","srcPort","dstIP","srcIP") 
state1 = 'syn' 
state2 = 'established' 
dt_state1 <- subset(F1_in, state == state2) 
setkey(dt_state1, keys) 
dt_state2 <- subset(F1_in, state == state1) 
setkey(dt_state2, keys) 

dt_state1 %>% 
    filter("state" == 'syn') %>% 
    left_join(filter(dt_state2, "state" == 'established'), by = keys) %>% 
    mutate(timestamp_diff = timestamp.x - timestamp.y) 

Ich änderte auch die dt des zweiten Filters. Aber es gibt keine Veränderung überhaupt in dt_state1 ..

+0

meine Antwort aktualisiert sehen. Ich habe die Schritte hinzugefügt, die ich vor dem linken Join verwendet habe. Zwei Probleme mit Ihrem Code: 1. Verwenden Sie nicht 'subset', sondern' ''. Dies gilt insbesondere für data.tables, da der Vorteil von "subset" stark reduziert ist. Statt 'dt_state1 <- Teilmenge (F1_in, state == state2)', mache 'dt_state1 <- F1_in [state == 'syn',]' 2. Verwende 'setDT' anstelle von' as.data.table'. Es erstellt eine data.table durch Verweis, die viel effizienter ist. 3. Verwenden Sie 'setkeyv' anstelle von' setkey', wenn Sie mit einem Vektor von Strings arbeiten. – lmo

Antwort

2

Wenn Ihr Ziel Unterschiede des Zeitstempels zwischen den beiden Daten zu nehmen ist.Tische, an denen sie den gleichen Schlüssel beide teilen, könnten Sie kommen verwenden links, und dann die Differenz berechnen:

# get stuff set up 
library(data.table) 
# convert data.frames to data.tables by reference 
setDT(dt_state1) 
setDT(dt_state2) 
# set keys 
setkey(dt_state1, record, dstPort, srcPort, proto, dstIP, srcIP) 
setkey(dt_state2, record, dstPort, srcPort, proto, dstIP, srcIP) 


# perform left join and get timestamp difference 
dt_state1[dt_state2, timestamp - i.timestamp] 

[1] 42999457440 -17000122838 -4999842180 47999198168 -12000382110  -101452  NA 

Dieses eine LEFT JOIN führt und subtrahiert (die die Beobachtungen in dt_state1 Teilmengen nur die Anwesenden in dt_state2 enthalten) Der Zeitstempel von dt_state2 von dt_state1.

Der erste Eintrag des zurückgegebenen Vektors ist der Wert, den Sie in Ihrem Beispiel aufgelistet haben.

Daten

dt_state1 <- read.table(header=T, text=" 
record dstPort srcPort proto dstIP srcIP state  timestamp 
1: state  80 32768 tcp 192.168.101.5 192.168.101.89 syn 1466580661185059 
2: state  80 32768 tcp 192.168.101.5 192.168.101.89 syn_ack 1466520661604781 
3: state  80 32768 tcp 192.168.101.5 192.168.101.89 close 1466532661885439 
4: state  80 55555 tcp 192.168.101.5 192.168.101.89 syn 1466532661885440") 

dt_state2 <- read.table(header=T, text=" 
record dstPort srcPort proto  dstIP srcIP state timestamp 
1: state  80 32768 tcp 192.168.101.5 192.168.101.89 established 1466537661727619 
2: state  80 32768 tcp 192.168.101.5 192.168.101.89 close 1466532661986891 
3: state  80 44444 tcp 192.168.101.5 192.168.101.89 established 1466537661727619") 
+0

Ich habe meinen Beitrag mit einer Antwort auf Ihren Vorschlag aktualisiert. – muehsi

0
library(dplyr) 

dt_state1 %>% 
    filter(state == 'syn') %>% 
    left_join(filter(dt_state2, state == 'established), by = insert all you keys here) %>% 
    mutate(timestamp_diff = timestamp.x - timestamp.y) 
+0

Ich habe meinen Beitrag mit einer Antwort auf Ihren Vorschlag aktualisiert. – muehsi

+0

Es wird dt_state1 nicht ändern, aber Sie können dt_state1 <- ... vor dem Code setzen. Auch ich habe das dt_state2 in Join korrigiert, danke fürs merken. – toni057