2016-07-09 4 views
2

Ich habe folgenden DatenrahmenAlternative zur langen Liste der verschachtelten ifelse Anweisung mit mehreren Bedingungen

structure(list(FY = c("2015-2016", "2015-2016", "2015-2016", 
"2015-2016"), YEARMN = structure(c(2015.25, 2015.25, 2015.25, 
2015.25), class = "yearmon"), BRAND = c("3M CAR CARE", "CAR CARE 3M", 
"CAR CARE 3M", "CAR CARE 3M"), variable = structure(c(1L, 
2L, 3L, 4L), .Label = c("IstWEEKRent", "IIndWEEKRent", "IIIrdWEEKRent", 
"IVthWEEKRent", "mymonth"), class = "factor"), value = c("0", 
"17500", "85000", "212500"), mymonth = c("Apr", "Apr", "Apr", 
"Apr")), .Names = c("FY", "YEARMN", "BRAND", "variable", "value", 
"mymonth"), row.names = c(NA, 4L), class = "data.frame") 

Der tatsächliche Datenrahmen wie folgt aussieht:

  FY YEARMN  BRAND  variable value mymonth 
1 2015-2016 Apr 2015 3M CAR CARE IstWEEKRent  0  Apr 
2 2015-2016 Apr 2015 CAR CARE 3M IIndWEEKRent 17500  Apr 
3 2015-2016 Apr 2015 CAR CARE 3M IIIrdWEEKRent 85000  Apr 
4 2015-2016 Apr 2015 CAR CARE 3M IVthWEEKRent 212500  Apr 

Die Säule meines Monats hat Monate ab April zu Mar ... und jeder Monat hat 4 Wochen in meinem Datensatz, der in der Spaltenvariablen angegeben ist. Ich versuche, eine Woche Zahl für die FY April zu erstellen - Mar, von 1 bis 48. Start Ich möchte 1 Woche Nummer geben, die den Zustand entspricht

variable == "IstWeekRent" & mymonth == "Apr" 

I verwendet ifelse Funktion dieses erhalten getan ... das funktioniert gut ... aber wenn ich schließen die gleiche in meine glänzende Anwendung ich die folgende Fehlermeldung erhalten:

Error in parse(file, keep.source = FALSE, srcfile = src, encoding = enc) : 
    contextstack overflow at line 2870 

Mein aktueller ifelse Bedingungsanweisung sieht wie folgt aus:

trndR$weeks <- ifelse(trndR$mymonth == "Apr" & trndR$variable == "IstWEEKRent", 1, 
       ifelse(trndR$mymonth == "Apr" & trndR$variable == "IIndWEEKRent", 2, 
       ifelse(trndR$mymonth == "Apr" & trndR$variable == "IIIrdWEEKRent", 3, 
       ifelse(trndR$mymonth == "Apr" & trndR$variable == "IVthWEEKRent", 4, 
       ifelse(trndR$mymonth == "May" & trndR$variable == "IstWEEKRent", 5, 
       ifelse(trndR$mymonth == "May" & trndR$variable == "IIndWEEKRent", 6, 

trndR ist der Name meines df und die Bedingung erstreckt sich bis 48.

Ich fand heraus, dass ich nur bis zu 50 verschachtelte ifelse Bedingung haben kann ... aber nicht ganz sicher, wie dies zu beheben ist. Ich lese über Anwendungsfunktion, weiß aber nicht, wie man es in diesem Fall verwendet.

+0

Sind die Daten sortiert? Die Daten, die Sie angezeigt haben, sehen so aus, als hätten Sie eine konsistente 1 Zeile pro Woche. In diesem Fall würde die Zeilennummer wahrscheinlich für Ihre "Wochen" -Spalte ausreichen. – rosscova

Antwort

2

1) Versuchen Sie dies:

mos <- month.abb[c(4:12, 1:3)] # Apr, May, ...., Dec, Jan, Feb, Mar 
transform(trndR, weeks = 4 * (match(mymonth, mos)-1) + as.numeric(variable)) 

dieser mit trndR in Frage gestellt zu geben:

  FY YEARMN  BRAND  variable value mymonth weeks 
1 2015-2016 2015.25 3M CAR CARE IstWEEKRent  0  Apr  1 
2 2015-2016 2015.25 CAR CARE 3M IIndWEEKRent 17500  Apr  2 
3 2015-2016 2015.25 CAR CARE 3M IIIrdWEEKRent 85000  Apr  3 
4 2015-2016 2015.25 CAR CARE 3M IVthWEEKRent 212500  Apr  4 

Dies sollte auch funktionieren, wenn die Zeilen nicht sortiert und auch wenn es fehlen Wochen.

1a) Diese Alternative ist kürzer (nur eine Zeile), aber vielleicht nicht so klar:

transform(trndR, weeks = 4*((match(mymonth, month.abb)-4) %% 12) + as.numeric(variable)) 

2) Wenn die Zeilen sortiert werden und es gibt keine fehlenden Wochen, dann würde dies funktionieren wie gut

transform(trndR, weeks = 1:nrow(trndR)) 
+0

Wie konvertiert 'as.numeric' die Zeichenfolgen in Zahlen? Ich kann sehen, dass es möglich ist, aber ich kann es (nur diese Umwandlung) nicht für mich arbeiten lassen. – rosscova

+0

Sie sind kein Charakter - sie sind ein Faktor. Probiere 'str (trndR)' –

+0

Ah, das habe ich nicht bemerkt! Macht das Problem viel einfacher! Vielen Dank. – rosscova

1

Aus dem Aussehen Ihrer Daten sollten Sie nur sicherstellen können, dass alles in der richtigen Reihenfolge ist, dann rufen Sie jede Zeile eine bestimmte Woche. Zum Beispiel (leicht verändert nach G.Grothendieck mir darauf hingewiesen, dass die variable Spalte Faktor, ihre Antwort als meine mehr ordentlich scheint, aber ich werde dies im Fall hier sowieso verlassen ist es von Interesse):

# get a value from 1 to 4, representing the `variable` column numerically 
trndR$weeks <- as.numeric(trndR$variable) 

# now sort the dataframe by `YEARMN` and `weeks` respectively to make sure everything is in order 
trndR <- trndR[ with(trndR, order(YEARMN, weeks)), ] 

# and replace that new `weeks` column with a sequence 
trndR$weeks <- seq_along(trndR$weeks) 

es sieht aus wie Ihre Daten ein Geschäftsjahr enthält, aber wenn nicht, können Sie die letzte Zeile des oben umschreiben es pro Geschäftsjahr anzuwenden (jedes FY unter der Annahme, vollständig in ihrem Datensatz dargestellt wird):

library(data.table) 
setDT(trndR)[ , weeks := seq_len(48), by = FY ] 
+0

Vielen Dank .... Ich habe Ihre Lösung versucht ...Allerdings füllte die seq_along die Spaltenwochen mit fortlaufenden Zahlen von 1 bis 1256 ... während ich nach einer Wochennummer suchte, die zwischen 1 und 48 liegt (unter Berücksichtigung von 4 Wochen pro Monat). Vielen Dank noch einmal ... Ihre Lösung hat mir sicherlich geholfen, eine andere Lösung zu kennen ... Ich habe mich seit dem letzten Morgen damit herumgeschlagen. Und ich habe mit FY subsettiert, bevor ich das ifelse anwendete. – Apricot

+1

Haben Sie den letzten Abschnitt (mit 'data.table') verwendet? Das sollte die lange Sequenz vermeiden, von der du sprichst. Wie auch immer, ich bin froh, dass du eine Lösung gefunden hast. – rosscova

Verwandte Themen