2017-12-12 5 views
0

Ich habe die Anzahl der Ereignisse (in Gruppe 1) über einen Zeitraum für jede Gruppe (in Gruppe 2) durchgeführt. Ich versuche, Ereignisse der Gruppe 1 in einzelne Spalten zu verteilen und Gruppe 2 und Zeitstempel als Zeilen zu verwenden. Jede Zelle enthält die Anzahl der Ereignisse über einen Zeitraum (aktuelles Datum der letzten 4 Tage).Anzahl/Summe der Füllung basierend auf der vorherigen Anzahl der Reihen im Zeitverlauf

Siehe Beispiel unten, für jede Gruppe 2 (I & II) habe ich die Ereignisse A und L in Gruppe 1 innerhalb von 4 Tagen gezählt.

dates = as.Date(c("2011-10-09", 
    "2011-10-15", 
    "2011-10-16", 
    "2011-10-18", 
    "2011-10-21", 
    "2011-10-22", 
    "2011-10-24")) 
group1=c("A", 
    "A", 
    "A", 
    "A", 
    "L", 
    "L", 
    "A") 
group2=c("I", 
    "I", 
    "I", 
    "I", 
    "I", 
    "I", 
    "II") 

df1 <- data.frame(dates, group1, group2) 

Mit dplyr Rohren konnte ich die folgende Tabelle erzeugen (siehe auch Count event types over time series by multiple conditions)

df1 %>% 
    group_by(group1, group2) %>% 
    mutate(count = sapply(dates 
        , function(x){ 
         sum(dates <= x & dates > (x-4)) 
         })) 


    dates group1 group2 count 
    <date> <fctr> <fctr> <int> 
1 2011-10-09  A  I  1 
2 2011-10-15  A  I  1 
3 2011-10-16  A  I  2 
4 2011-10-18  A  I  3 
5 2011-10-21  L  I  1 
6 2011-10-22  L  I  2 
7 2011-10-24  A  II  1 

Schließlich möchte ich eine Tabelle erhalten, ähnlich wie mit Events A & L zählt Update nach Daten (Zeitraum = aktuelles Datum - 4 Tage) in beiden I & II (Gruppe 2).

  dates group1 group2 count (A) count (L) 
    1 2011-10-09  A  I  1   0 
    2 2011-10-15  A  I  1   0 
    3 2011-10-16  A  I  2   0 
    4 2011-10-18  A  I  3   0 
    5 2011-10-21  L  I  0   1 
    6 2011-10-22  L  I  0   2 
    7 2011-10-24  A  II  1   0 

In einem größeren Datensatz nicht alle Ereignisse in Gruppe 1 erscheint in jeder Gruppe 2 Wie kann ich diese leeren Zellen aktualisieren, so dass es entweder 1) die Übertragung der Zählung von der vorherigen Zeile oder 2) die Zählung basierend auf dem aktualisierten Zeitstempel/Zeitraum aktualisieren?

Danke!

+0

In Ihrem Beispiel Sie zeigen, '0' für 'count (A)' in den Reihen 5 und 6. Es gab jedoch ein Ereignis (am 18.), das innerhalb von 4 Tagen vom 21. (Reihe 5) war, obwohl die Zählung am 21. auf "0" zurückgehen sollte. Ist Ihr Beispiel eine genaue Darstellung dessen, wie Daten angezeigt werden sollen? Genauso, wenn zwei Einträge für einen Tag vorhanden sind, möchten Sie jeweils eine Zeile? Gibt es einen Grund, warum Sie die Spalten "group1" und "group2" beibehalten möchten, anstatt nur die Anzahl der Ereignisse anzuzeigen? Versuchen Sie immer noch separate Zählungen für jede Untergruppe der Gruppe 2 durchzuführen? –

+0

Viele davon können wir mit einem motivierenden Beispiel beantworten. In jeder der beiden vorherigen Fragen und insbesondere jetzt ist unklar, was das gewünschte Ergebnis ist, weil unklar ist, wie es verwendet wird. –

Antwort

0

Während es noch ein wenig unklar ist, was Sie wollen (siehe Kommentare zu der Frage), hier sind zwei mögliche Ansätze.

Wenn Sie nur die count Spalte aus (aus irgendeinem Grund) verteilen und mit Nullen (ob es ein Ereignis in den vorangegangenen 4 Tagen oder nicht gab) und immer noch durch die group2 Aufschlüsselung zählen (obwohl Sie werden nur von group1 beschriftet) und lassen Sie die Ereignisdetails (wie Ihr Beispiel in Ihrer Frage), können Sie nur eine Spalte mit den gewünschten Etiketten erstellen, dann verwenden Sie spread, um die neuen Spalten zu erstellen. Diese

df1 %>% 
    group_by(group1, group2) %>% 
    mutate(count = sapply(dates 
         , function(x){ 
          sum(dates <= x & dates > (x-4)) 
         })) %>% 
    ungroup() %>% 
    mutate(toSpread = paste0("Count (", group1, ")")) %>% 
    spread(toSpread, count, fill = 0) 

gibt diese:

 dates group1 group2 `Count (A)` `Count (L)` 
*  <date> <fctr> <fctr>  <dbl>  <dbl> 
1 2011-10-09  A  I   1   0 
2 2011-10-15  A  I   1   0 
3 2011-10-16  A  I   2   0 
4 2011-10-18  A  I   3   0 
5 2011-10-21  L  I   0   1 
6 2011-10-22  L  I   0   2 
7 2011-10-24  A  II   1   0 

, der die Ausgabe entspricht, die Sie in Ihrer Frage gezeigt haben. Wenn Sie jedoch an einem beliebigen Tag mit einem Ereignis sehen möchten, wie viele Ereignisse in der Gruppe1 aufgetreten sind, müssen Sie noch ein Stück zurückgehen. Dazu müssen Sie einen neuen Datenrahmen mit den gewünschten Daten generieren - mit einer Zeile für jede Gruppe. Dies ist leicht zu erreichen mit complete von tidyr. Anschließend können Sie jeden dieser Ereignisse auf Ereignisse überprüfen, die in den vorangegangenen vier Tagen für diese Gruppe aufgetreten sind.

df1 %>% 
    select(dates, group1) %>% 
    complete(dates, group1) %>% 
    mutate(count = sapply(1:n() 
         , function(idx){ 
          sum(df1$dates <= dates[idx] & 
           df1$dates > (dates[idx]-4) & 
           df1$group1 == group1[idx]) 
         })) %>% 
    mutate(group1 = paste0("Count (", group1, ")")) %>% 
    spread(group1, count, fill = 0) 

kehrt:

# A tibble: 7 x 3 
     dates `Count (A)` `Count (L)` 
*  <date>  <dbl>  <dbl> 
1 2011-10-09   1   0 
2 2011-10-15   1   0 
3 2011-10-16   2   0 
4 2011-10-18   3   0 
5 2011-10-21   1   1 
6 2011-10-22   0   2 
7 2011-10-24   1   2 

Beachten Sie, dass, wenn Sie möchten Tage einschließen, für die es keine Ereignisse waren, können Sie tun, dass die Daten, indem Sie in complete überprüft werden sollen.Zum Beispiel:

df1 %>% 
    select(dates, group1) %>% 
    complete(dates = full_seq(dates, 1), group1) %>% 
    mutate(count = sapply(1:n() 
         , function(idx){ 
          sum(df1$dates <= dates[idx] & 
           df1$dates > (dates[idx]-4) & 
           df1$group1 == group1[idx]) 
         })) %>% 
    mutate(group1 = paste0("Count (", group1, ")")) %>% 
    spread(group1, count, fill = 0) 

kehrt:

 dates `Count (A)` `Count (L)` 
*  <date>  <dbl>  <dbl> 
1 2011-10-09   1   0 
2 2011-10-10   1   0 
3 2011-10-11   1   0 
4 2011-10-12   1   0 
5 2011-10-13   0   0 
6 2011-10-14   0   0 
7 2011-10-15   1   0 
8 2011-10-16   2   0 
9 2011-10-17   2   0 
10 2011-10-18   3   0 
11 2011-10-19   2   0 
12 2011-10-20   1   0 
13 2011-10-21   1   1 
14 2011-10-22   0   2 
15 2011-10-23   0   2 
16 2011-10-24   1   2 

auf die Kommentare Basierend, ich glaube ich das Ziel schließlich bin zu verstehen. Erstens würde ich anfangen, wie oben beschrieben, einen „langen“ Datenrahmen mit den Zählungen für jede Gruppe 1/Gruppe 2 Paare für jeden Tag zu schaffen:

fullDateCounts <- 
    df1 %>% 
    select(dates, group1, group2) %>% 
    complete(dates = full_seq(dates, 1), group1, group2) %>% 
    mutate(count = sapply(1:n() 
         , function(idx){ 
          sum(df1$dates <= dates[idx] & 
           df1$dates > (dates[idx]-4) & 
           df1$group1 == group1[idx] & 
           df1$group2 == group2[idx] 
          ) 
         })) 

Anfang der ist:

 dates group1 group2 count 
     <date> <fctr> <fctr> <int> 
1 2011-10-09  A  I  1 
2 2011-10-09  A  II  0 
3 2011-10-09  L  I  0 
4 2011-10-09  L  II  0 
5 2011-10-10  A  I  1 
6 2011-10-10  A  II  0 
7 2011-10-10  L  I  0 
8 2011-10-10  L  II  0 
9 2011-10-11  A  I  1 
10 2011-10-11  A  II  0 
# ... with 54 more rows 

Von dort aus, wenn Sie wirklich eine große Form konvertieren, dann können Sie entweder tun dies mit einer Zeile für jeden group2 (oder Gruppe 1, wenn Sie die Spaltennamen wechseln):

fullDateCounts %>% 
    mutate(group1 = paste0("Count (", group1, ")")) %>% 
    spread(group1, count, fill = 0) 

kehrt:

 dates group2 `Count (A)` `Count (L)` 
*  <date> <fctr>  <dbl>  <dbl> 
1 2011-10-09  I   1   0 
2 2011-10-09  II   0   0 
3 2011-10-10  I   1   0 
4 2011-10-10  II   0   0 
5 2011-10-11  I   1   0 
6 2011-10-11  II   0   0 
7 2011-10-12  I   1   0 
8 2011-10-12  II   0   0 
9 2011-10-13  I   0   0 
10 2011-10-13  II   0   0 
# ... with 22 more rows 

Oder können Sie eine Spalte für jede Gruppe 1/Gruppe 2 Paar erzeugen:

fullDateCounts %>% 
    mutate(toSpread = paste0("Count (", group1, "-", group2, ")")) %>% 
    select(-group1, -group2) %>% 
    spread(toSpread, count, fill = 0) 

kehrt

 dates `Count (A-I)` `Count (A-II)` `Count (L-I)` `Count (L-II)` 
*  <date>   <dbl>   <dbl>   <dbl>   <dbl> 
1 2011-10-09    1    0    0    0 
2 2011-10-10    1    0    0    0 
3 2011-10-11    1    0    0    0 
4 2011-10-12    1    0    0    0 
5 2011-10-13    0    0    0    0 
6 2011-10-14    0    0    0    0 
7 2011-10-15    1    0    0    0 
8 2011-10-16    2    0    0    0 
9 2011-10-17    2    0    0    0 
10 2011-10-18    3    0    0    0 
11 2011-10-19    2    0    0    0 
12 2011-10-20    1    0    0    0 
13 2011-10-21    1    0    1    0 
14 2011-10-22    0    0    2    0 
15 2011-10-23    0    0    2    0 
16 2011-10-24    0    1    2    0 
+0

Tatsächlich sollte count (A) in den Zeilen 5 und 6 1 und 0 sein, wo die Zählungen innerhalb jeder Gruppe 2 berechnet werden. Danke, dass Sie dies hervorgehoben haben. Datum, Gruppe 1 und Gruppe 2 in Zusammenhang setzen. In meinem Datensatz bezieht sich Gruppe 2 auf Teilnehmer-IDs in der Studie, und Unterkategorien der Gruppe 1 beziehen sich auf Ereignisse, die in jedem Teilnehmer aufgezeichnet sind. Die Datumsspalte bezieht sich auf jedes Ereignis von Gruppe 1, das aufgetreten ist. Nicht alle Teilnehmer (Gruppe2) berichteten über Ereignisse/Unterkategorien, die in Gruppe 1 gemessen wurden. – cyb

+0

Mit dieser Tabelle hoffe ich, dass bei jedem Ereignisdatum der Gruppe 1 jeder Teilnehmer (Gruppe 2 Unterkategorie) die X-Nummer von Ereignis A, Y-Nummer meldet von Event L usw. in den vorangegangenen 4 Tagen. Also ja, ich versuche immer noch, getrennte Zählungen für jede Gruppe 2 Untergruppe zu machen. Vielen Dank für Ihre Vorschläge! Ich nehme an, ich muss Select (dates, group1, group2) und group_by (group2) in der dplyr-Pipe hinzufügen, um die Antwort zu aktualisieren? – cyb

+0

Ich denke, dass die Bearbeitung, die ich gerade gemacht habe, deine Bedürfnisse anspricht. In der Zukunft würde ich vorschlagen, beschreibende Etiketten (z. B. Ereignis und Teilnehmer) zu verwenden, um klarer zu machen, was Sie erreichen möchten. –

Verwandte Themen