Ich muss Teilmengen oder Gruppen meiner Daten basierend auf zwei verschiedenen Bedingungen erstellen. Dies ist ein Beispiel für die Struktur der Daten:

df <- data.frame(id = c("a", "a", "a", "b", "d", "b", "b", "c", "d", "e"),
               kpi = c ("rev", "rev", "rev", "rev", "rev", "fte", "fte", "fte", "fte", "fte"),
               value = c(100, 150, 200, 50, 70, 3, 5, 8, 9, 3))

       id kpi value
    1   a rev   100
    2   a rev   150
    3   a rev   200
    4   b rev    50
    5   d rev    70
    6   b fte     3
    7   b fte     5
    8   c fte     8
    9   d fte     9
    10  e fte     3
  • Die erste Spalte enthält IDs für Unternehmen. Es kann mehrere Zeilen für jede ID geben, da sie Daten für mehrere Monate (Monatsspalte nicht in den Beispieldaten enthalten) und Daten für rev (Umsatz) und fte (Vollzeitäquivalent) enthalten können.

  • Ich möchte jedes Unternehmen auswählen, für das der fte-Durchschnitt in einem bestimmten Bereich liegt: 1-5

    • Zum Beispiel sollte Unternehmen b einbezogen werden, da es einen durchschnittlichen fte von 4 hat (in einem Monat 3 in einem anderen 5), Unternehmen d sollte ausgeschlossen werden, da es einen höheren fte hat.
  • Für die enthaltenen möchte ich, dass alle Zeilen im Datenrahmen bleiben, daher auch die Zeilen mit den Drehzahldaten. Ziel ist es, einen durchschnittlichen Umsatz für Kohorten von Unternehmen mit bestimmten FTE-Zahlen zu berechnen.

  • Der Rahmen new.data mit den genannten Bedingungen sollte für die Beispieldaten folgendermaßen aussehen:

     df <- data.frame(id = c("b", "b", "b", "e"),
                   kpi = c("rev", "fte", "fte", "fte"), value = c(50, 3, 5, 3))
    
          id kpi value
        1  b rev    50
        2  b fte     3
        3  b fte     5
        4  e fte     3
    

    Es würde auf einen Datenrahmen von ungefähr 40.000 Zeilen angewendet.

    Ich habe bereits einige Nachforschungen angestellt und viel über das Erstellen von Teilmengen mit mehreren Bedingungen herausgefunden, aber nichts, was ich auf mein spezifisches Problem anwenden könnte. Es tut mir leid, wenn dies eine offensichtliche Frage ist, ich bin ein R-Neuling und könnte wirklich Hilfe gebrauchen!

    Wenn ich das Problem nicht klar genug spezifiziert habe, können Sie es gerne fragen und ich werde versuchen, es klarer zu erklären!

    Vielen Dank im Voraus!

    2
    Luna 17 Apr. 2018 im 16:25

    4 Antworten

    Beste Antwort

    Gruppieren Sie nach ID und filtern Sie dann diejenigen, die die Bedingung erfüllen:

    library(dplyr)
    
    df %>% 
       group_by(id) %>%
       filter(between(mean(value[kpi == "fte"]), 1, 5)) %>%
       ungroup
    

    Geben:

    # A tibble: 4 x 3
      id    kpi   value
      <fct> <fct> <dbl>
    1 b     rev     50.
    2 b     fte      3.
    3 b     fte      5.
    4 e     fte      3.
    
    3
    G. Grothendieck 17 Apr. 2018 im 13:37

    In Basis R können Sie mit ave eine temporäre Variable erstellen und diese Variable dann verwenden.

    a <- ave(df$value, df$id, df$kpi, FUN = mean)
    new <- df[1 <= a & a <= 5, ]
    new
    #   id kpi value
    #6   b fte     3
    #7   b fte     5
    #10  e fte     3
    

    Entfernen Sie nun, was Sie nicht mehr benötigen.

    rm(a)    # clean up
    
    1
    Rui Barradas 17 Apr. 2018 im 13:40

    Sie können eine tidyverse Lösung ausprobieren

    library(tidyverse)
    df %>%
      group_by(id,kpi) %>% 
      mutate(Mean=mean(value)) %>% 
      mutate(gr= between(Mean, 1, 5)) %>% 
      group_by(id) %>% 
      mutate(gr2 = ifelse(any(gr) & kpi == "rev",T, F)) %>% 
      filter(gr | gr2) %>% 
      select(1:3)
    # A tibble: 4 x 3
    # Groups:   id [2]
      id    kpi   value
      <fct> <fct> <dbl>
    1 b     rev     50.
    2 b     fte      3.
    3 b     fte      5.
    4 e     fte      3.
    

    Ich habe jeden Schritt eingeschlossen, um zu veranschaulichen, was die Idee ist.

    1. Berechnen Sie zuerst den Mittelwert für jeden id und kpi Wert.
    2. Fügen Sie TRUE hinzu, wenn der Mittelwert zwischen 1 und 5 liegt
    3. erneut nach ID gruppieren, um die entsprechenden rev Werte zu filtern
    4. Filter
    5. Wählen Sie die richtigen Spalten aus.
    0
    Roman 17 Apr. 2018 im 13:42

    Hier ist eine Lösung mit data.table:

    library("data.table")
    setDT(df)
    df[df[kpi=="fte", if (between(mean(value), 1, 5)) id, id], on="id"][, -c("V1")]
    # > df[df[kpi=="fte", if (between(mean(value), 1, 5)) id, id], on="id"][, -c("V1")]
    #    id kpi value
    # 1:  b rev    50
    # 2:  b fte     3
    # 3:  b fte     5
    # 4:  e fte     3
    

    Oder

    df[df[kpi=="fte", if (between(mean(value), 1, 5)) id, id][,-2], on="id"][]
    
    0
    jogo 17 Apr. 2018 im 14:07