2017-11-18 3 views
0

Vermeintliche ich einen R-Datenrahmen haben, die wie folgt aussieht:Wie Spalte in r Datenrahmen Rang basierend auf einer anderen Spalte

#sample data frame 
df <- data.frame(
customer_id = c(568468,568468,568468,568468,568468,568468), 
customer = c('paramount','paramount','paramount','paramount','paramount','paramount'), 
start_date = as.Date(c('2016-03-15','2016-03-15','2016-03-15','2016-03-15','2016-03-15','2016-03-15')), 
occured_on = as.POSIXct(c('2017-08-08 20:05:00','2017-08-08 20:30:00','2017-08-11 21:13:00','2017-08-11 21:30:00','2017-08-31 05:16:00','2017-08-31 05:30:00')), 
old_plan = c('a',NA,'b',NA,'b',NA), 
old_price = c(NA,29,NA,99,NA,82.5), 
old_recurrence = c('monthly',NA,'monthly',NA,'annually',NA), 
new_plan = c('b',NA,'b',NA,'c',NA), 
new_price = c(NA,99,NA,82.5,NA,349), 
new_recurrence = c('monthly',NA,'annually',NA,'monthly',NA) 
); 

Aufgabe:

Rang der old_plan, old_price, old_recurrence als der erste in jeder Gruppe basierend auf der min occured_on time ... und dem new_plan, new_price, new_recurrence, basierend auf der max occured_on time ... so dass mein resultierender Datenrahmen den ersten alten Plan, Preis und Wiederholung hätte, und der letzte neue Planpreis und Wiederholung. NAs sollten entfernt/nicht berücksichtigt werden. Die sich ergebende Datenrahmen sollte wie folgt aussehen:

customer_id customer start_date old_plan old_price old_recurrence new_plan new_price new_recurrence 
568468 paramount 2016-03-15  a  29  monthly  c  349  monthly 

oder wenn Sie in Ihrem Code

result_df <- data.frame(
customer_id = 568468, 
customer = 'paramount', 
start_date = "2016-03-15", 
old_plan = 'a', 
old_price = 29, 
old_recurrence = 'monthly', 
new_plan = 'c', 
new_price = 349, 
new_recurrence = 'monthly' 
) 

ich ich bin nahe Funktionen diese fühlen sehen wollen, wie ...

df$old_plan_rank <- rank(df$old_plan, na.last = "keep", ties.method = "min") 
df$new_recurrence_rank <- rank(df$new_recurrence, na.last = "keep", ties.method = "max") 

mit Ausnahme der Rangfolge basierend auf der Reihenfolge oder alphabetisch/numerisch, nicht in der Reihenfolge, in der sie tatsächlich aufgetreten ist, basierend auf der Spalte "aufgetreten". Ich weiß nicht, wie ich eine Spalte angeben soll, auf der ich rangieren kann.

Hilfe?

Antwort

1

Eine Lösung mit dplyr.

library(dplyr) 

df2 <- df %>% 
    arrange(customer_id, start_date, occured_on) %>% 
    group_by(customer_id, customer, start_date) %>% 
    summarise(old_plan = first(old_plan[!is.na(old_plan)]), 
      old_price = first(old_price[!is.na(old_price)]), 
      old_recurrence = first(old_recurrence[!is.na(old_recurrence)]), 
      new_plan = last(new_plan[!is.na(new_plan)]), 
      new_price = last(new_price[!is.na(new_price)]), 
      new_recurrence = last(new_recurrence[!is.na(new_recurrence)])) %>% 
    ungroup() %>% 
    as.data.frame() 
df2 
# customer_id customer start_date old_plan old_price old_recurrence new_plan new_price new_recurrence 
# 1  568468 paramount 2016-03-15  a  29  monthly  c  349  monthly 

Erklärung

arrange(customer_id, start_date, occured_on) ist die Spalten zu sortieren. Es sortiert die Spalten nach customer_id und dann start_date, schließlich occured_on.

group_by(customer_id, customer, start_date) Mittel die folgende Operation in jeder Gruppe auf customer_id, customer und start_date basierend auszuführen.

summarise generiert eine einzelne Zusammenfassungsausgabe für jede Variable.

Für jede Variable, nehmen Sie old_plan als Beispiel, ich verwendete old_plan[!is.na(old_plan), um die Nicht-NA-Werte dieser Spalte zu extrahieren. Danach können first und last das erste oder das letzte Element jener Werte extrahieren, die dem Minimum und Maximum in Bezug auf die Zeit entsprechen.

ungroup() ist die Gruppierung zu entfernen. as.data.frame() ist optional, das das Objekt tibble in streng data.frame Objekt konvertiert.

+0

ERSTAUNLICH! Ich danke dir sehr! Ich glaube nicht, dass ich es herausgefunden hätte, dass es den Weg gegangen ist, auf dem ich war! –

Verwandte Themen