2016-05-16 10 views
0

Ich bin ziemlich neu in R und kann nicht herausfinden, wie ich mit einem relativ einfachen Problem umgehen soll. Ich möchte die Zeilen der Spalte 'DAUER' nach 'TRIAL_INDEX' summieren, aber dann nur die ersten Zeilen, in denen die Werte von 'X_POSITION' zunehmen. Ich möchte nur die erste Runde innerhalb einer Prüfung summieren, in der X größer wird. erste Zeilen eines vereinfachten Datenrahmen:R: Summenzeilen von Spalte A bis konditionierten Wert in Spalte B

TRIAL_INDEX DURATION X_POSITION 
1   1  204  314.5 
2   1  172  471.6    
3   1  186  570.4   
4   1  670  539.5   
5   1  186  503.6   
6   2  134  306.8   
7   2  182  503.3    
8   2  806  555.7   
9   2  323  490.0   

so zum TRIAL_INDEX 1 ist nur die ersten drei Werte der Dauer sollen (204 + 172 + 186) hinzugefügt werden, wie dies in der X den höchsten Wert hat bisher (. gehen durch die Datenrahmen Zeile für Zeile)

Das sollte gewünschte Ausgabe in etwa so aussehen:

TRIAL_INDEX DURATION X_POSITION FIRST_PASS_TIME 
1   1  204  314.5    562 
2   1  172  471.6    562 
3   1  186  570.4    562 
4   1  670  539.5    562 
5   1  186  503.6    562 
6   2  134  306.8   1122 
7   2  182  503.3   1122 
8   2  806  555.7   1122 
9   2  323  490.0   1122 

Ich habe versucht, dplyr zu verwenden, um einen neuen Datenrahmen zu generieren, der mit meinem ursprünglichen Datenrahmen zusammengeführt werden kann. Der Code funktioniert jedoch nicht, und ich bin mir auch nicht sicher, wie sichergestellt werden kann, dass nur die ersten Zeilen pro Test mit steigenden Werten für X_POSITION hinzugefügt werden.

FirstPassRT = dat %>% 
      group_by(TRIAL_INDEX) %>% 
      filter(dplyr::lag(dat$X_POSITION,1) > dat$X_POSITION) %>% 
      summarise(FIRST_PASS_TIME=sum(DURATION)) 

Jede Hilfe und Vorschläge werden sehr geschätzt!

+0

Ihre 'X_POSITION' ist nicht numerisch, also wie soll R wissen, ob es zunimmt oder nicht? Ich würde vermuten, dass es die zugrundeliegende Integer-Repräsentation verwendet (wenn diese Faktoren) und Warnungen wirft. Sehen Sie [hier] (http://stackoverflow.com/questions/15236440/as-numeric-with-comma-decimal-separators) zum Beispiel. –

+0

Danke David, guter Punkt. Ich habe die X_POSITION-Werte in numerische geändert, ein kleiner Anfängerfehler beim Einlesen der Daten. Trotzdem scheint meine gewünschte Ausgabe nicht zu bekommen ... – Saskia

Antwort

0
library(data.table) 
dt = as.data.table(df) # or setDT to convert in place 

# find the rows that will be used for summing DURATION 
idx = dt[, .I[1]:.I[min(.N, which(diff(X_POSITION) < 0), na.rm = T)], by = TRIAL_INDEX]$V1 

# sum the DURATION for those rows 
dt[idx, time := sum(DURATION), by = TRIAL_INDEX][, time := time[1], by = TRIAL_INDEX] 
dt 
# TRIAL_INDEX DURATION X_POSITION time 
#1:   1  204  314.5 562 
#2:   1  172  471.6 562 
#3:   1  186  570.4 562 
#4:   1  670  539.5 562 
#5:   1  186  503.6 562 
#6:   2  134  306.8 1122 
#7:   2  182  503.3 1122 
#8:   2  806  555.7 1122 
#9:   2  323  490.0 1122 
+0

Eddi, das ist großartig, vielen Dank! Ich habe versucht, für Loops zu schreiben, die extrem langsam sind, und das ist so ein schneller und kurzer Weg. – Saskia

1

Hier ist etwas, das man mit dplyr Paket ausprobieren können:

library(dplyr); 
dat %>% group_by(TRIAL_INDEX) %>% 
     mutate(IncLogic = X_POSITION > lag(X_POSITION, default = 0)) %>% 
     mutate(FIRST_PASS_TIME = sum(DURATION[IncLogic])) %>% 
     select(-IncLogic) 

Source: local data frame [9 x 4] 
Groups: TRIAL_INDEX [2] 

    TRIAL_INDEX DURATION X_POSITION FIRST_PASS_TIME 
     (int) (int)  (dbl)   (int) 
1   1  204  314.5    562 
2   1  172  471.6    562 
3   1  186  570.4    562 
4   1  670  539.5    562 
5   1  186  503.6    562 
6   2  134  306.8   1122 
7   2  182  503.3   1122 
8   2  806  555.7   1122 
9   2  323  490.0   1122 
+0

Wenn ich OP richtig lese, ist das nicht das, was sie wollen. Ändern Sie den Wert der Position 5 in Zeile 5 in 600 und führen Sie diese aus. – eddi

0

Wenn Sie es auf eine Zeile pro Versuch zusammenfassen wollen, können Sie wie folgt zusammenfassen verwenden:

library(dplyr) 

df <- data_frame(TRIAL_INDEX = c(1,1,1,1,1,2,2,2,2), 
       DURATION = c(204,172,186,670, 186,134,182,806, 323), 
       X_POSITION = c(314.5, 471.6, 570.4, 539.5, 503.6, 306.8, 503.3, 555.7, 490.0)) 

res <- df %>% 
    group_by(TRIAL_INDEX) %>% 
    mutate(x.increasing = ifelse(X_POSITION > lag(X_POSITION), TRUE, FALSE), 
     x.increasing = ifelse(is.na(x.increasing), TRUE, x.increasing)) %>% 
    filter(x.increasing == TRUE) %>% 
    summarize(FIRST_PASS_TIME = sum(X_POSITION)) 
res 

#Source: local data frame [2 x 2] 
# 
# TRIAL_INDEX FIRST_PASS_TIME 
#  (dbl)   (dbl) 
#1   1   1356.5 
#2   2   1365.8 
Verwandte Themen