2016-05-19 4 views
1

Ich habe Daten, die wie folgt aussehen:Unterschied zwischen Terminen in vielen Spalten in R

ID Date1    Date2    Date3 
A 2016-04-25 09:15:29 2016-04-25 14:01:19 2016-04-26 13:28:19 
B 2016-04-25 09:15:29 2016-04-25 14:01:19 2016-04-26 13:28:19 

Ich mag den Unterschied in Stunden zwischen jedem Zeitpunkt Kombination (im Idealfall nur vorwärts heißen ohne negative Unterschiede in der Zeit zu gehen). Ich weiß, wie dies manuell zu tun (calculating number of days between 2 columns of dates in data frame):

df$Date2_Date1 <- difftime(df$Date2,df$Date1, units = c("hours")) 

jedoch mein wirklicher Datenrahmen ist viel größer, und dies wäre sehr langweilig (aber möglich). Ich habe dies (Calculate pairwise-difference between each pair of columns in dataframe) lesen und diese (R: Compare all the columns pairwise in matrix), die mich führen, dies zu versuchen:

nm1 <- outer(colnames(df), colnames(df), paste, sep="_") 
indx1 <- which(lower.tri(nm1, diag=TRUE)) 
df2 <- outer(1:ncol(df), 1:ncol(df), 
      function(x,y) df[,x]-df[,y]) 

Was ich denke, ist immer mir nahe, aber mein idealer Ausgangs ist dies:

ID Date2_Date1 Date3_Date1 Date3_Date2 
A x hours  y hour  ... 
B .. 

Gibt es Schöne Lösungen dafür?

Antwort

3

Hier ist eine Art und Weise, basierend auf combn() und apply():

df <- data.frame(
    ID=c('A','B'), 
    Date1=as.POSIXct(c('2016-04-25 09:15:29','2016-04-25 09:15:29')), 
    Date2=as.POSIXct(c('2016-04-25 14:01:19','2016-04-25 14:01:19')), 
    Date3=as.POSIXct(c('2016-04-26 13:28:19','2016-04-26 13:28:19')), 
    stringsAsFactors=F 
); 

cmb <- combn(seq_len(ncol(df)-1L)+1L,2L); 
res <- abs(apply(cmb,2L,function(x) difftime(df[[x[1L]]],df[[x[2L]]],units='hours'))); 
colnames(res) <- apply(cmb,2L,function(x,cns) paste0(cns[x[1L]],'_',cns[x[2L]]),names(df)); 
res; 
##  Date1_Date2 Date1_Date3 Date2_Date3 
## [1,] 4.763889 28.21389  23.45 
## [2,] 4.763889 28.21389  23.45 
+1

Danke, das funktioniert. Ich habe ein paar Probleme mit meinen realen Daten. Ich denke, weil ich mehr ID-Spalten habe, um zu gruppieren. Entfernt "-1L" im cmb die ID col? – Pete900

+1

Ja, die '-1L' entfernt die 'ID'-Spalte, da sie nicht an der Kombinationsberechnung teilnehmen darf. Bezüglich der Gruppierung ging ich davon aus, dass Sie für diese Aufgabe nicht nach 'ID' gruppieren müssen, weil Ihr Beispielcode nicht nach 'ID' gruppiert (bezogen auf Ihre manuelle Lösung 'df $ Date2_Date1 <- difftime (df $ Date2, df $ Date1) , Einheiten = c ("Stunden")) '). – bgoldst

+1

Ja, du hast recht, ich brauche nichts zu gruppieren. Ich muss nur den Code anpassen, um "-2L" zu sein. Meine Schuld hätte ich genau nach Formattyp gepostet. – Pete900

Verwandte Themen