2016-04-28 17 views
2

Ich benutze data.table und ich versuche, eine neue Spalte, genannt "Saison", die eine Spalte mit der entsprechenden Saison, z. B. Sommer, Winter erstellt. .. basierend auf einer Spalte namens "MonthName".Hinzufügen von Jahreszeiten Spalte zu Datentabelle basierend auf Monatsdaten

Ich frage mich, ob es eine effizientere Möglichkeit gibt, einer Datentabelle basierend auf Monatswerten eine Saisonspalte hinzuzufügen.

Dies ist die erste 6 von 300.000 Beobachtungen, angenommen, dass die Tabelle "dt" heißt.

rrp   Year Month Finyear hourminute AvgPriceByTOD MonthName 
1: 35.27500  1999  1 1999  00:00  33.09037  Jan 
2: 21.01167  1999  1 1999  00:00  33.09037  Jan 
3: 25.28667  1999  2 1999  00:00  33.09037  Feb 
4: 18.42334  1999  2 1999  00:00  33.09037  Feb 
5: 16.67499  1999  2 1999  00:00  33.09037  Feb 
6: 18.90001  1999  2 1999  00:00  33.09037  Feb 

Ich habe den folgenden Code versucht:

dt[, Season := ifelse(MonthName = c("Jun", "Jul", "Aug"),"Winter", ifelse(MonthName = c("Dec", "Jan", "Feb"), "Summer", ifelse(MonthName = c("Sep", "Oct", "Nov"), "Spring" , ifelse(MonthName = c("Mar", "Apr", "May"), "Autumn", NA))))] 

Welche zurück:

rrp totaldemand Year Month Finyear hourminute AvgPriceByTOD MonthName Season 
1: 35.27500  1999  1 1999  00:00  33.09037  Jan  NA 
2: 21.01167  1999  1 1999  00:00  33.09037  Jan Summer 
3: 25.28667  1999  2 1999  00:00  33.09037  Feb Summer 
4: 18.42334  1999  2 1999  00:00  33.09037  Feb  NA 
5: 16.67499  1999  2 1999  00:00  33.09037  Feb  NA 
6: 18.90001  1999  2 1999  00:00  33.09037  Feb Summer 

ich den Fehler:

Warning messages: 
1: In MonthName == c("Jun", "Jul", "Aug") : 
    longer object length is not a multiple of shorter object length 
2: In MonthName == c("Dec", "Jan", "Feb") : 
    longer object length is not a multiple of shorter object length 
3: In MonthName == c("Sep", "Oct", "Nov") : 
    longer object length is not a multiple of shorter object length 
4: In MonthName == c("Mar", "Apr", "May") : 
    longer object length is not a multiple of shorter object length 

Daneben, aus Gründen, die ich weiß nicht, einige der Sommermonate sind korrekt zugewiesen "Sommer", aber andere sind NA zugeordnet, z. B. Zeilen 1 und 2 sollten beide Sommer sein, aber anders zurückkehren.

Vielen Dank im Voraus!

+1

Verwenden Sie 'MonthName% in% c (" Jun ", ...)', nicht '= ' – SymbolixAU

+2

und es ist kein ** Fehler **, es ist eine ** Warnung ** – SymbolixAU

+0

Es ist nicht ideal, da es erstellt und dann doppelte Ebenen, aber ich verwende in der Regel' cut' auf dem numerischen Monat: 'droplevels (cut (dt $ Monat, Pausen = c (0, 2, 5, 8, 11, 13), Labels = c ('Winter', 'Frühling', 'Sommer', 'Herbst', 'Winter')) ' – alistaire

Antwort

7

Eine recht einfache Art und Weise ist eine Lookup-Tabelle zu verwenden, Monatsnamen zu Jahreszeiten zur Karte:

# create a named vector where names are the month names and elements are seasons 
seasons <- rep(c("winter","spring","summer","fall"), each = 3) 
names(seasons) <- month.abb[c(6:12,1:5)] # thanks thelatemail for pointing out month.abb 
seasons 
#  Jun  Jul  Aug  Sep  Oct  Nov  Dec  Jan 
#"winter" "winter" "winter" "spring" "spring" "spring" "summer" "summer" 
#  Feb  Mar  Apr  May 
#"summer" "fall" "fall" "fall" 

Verwenden Sie es:

dt[, season := seasons[MonthName]] 

Daten:

dt <- setDT(read.table(text=" rrp   Year Month Finyear hourminute AvgPriceByTOD MonthName 
1: 35.27500  1999  1 1999  00:00  33.09037  Jan 
2: 21.01167  1999  1 1999  00:00  33.09037  Jan 
3: 25.28667  1999  2 1999  00:00  33.09037  Feb 
4: 18.42334  1999  2 1999  00:00  33.09037  Feb 
5: 16.67499  1999  2 1999  00:00  33.09037  Feb 
6: 18.90001  1999  2 1999  00:00  33.09037  Feb", 
    header = TRUE, stringsAsFactors = FALSE)) 
+0

Ha, ich nehme an du bist irgendwo in der südlichen Hemisphäre. – alistaire

+0

@alistaire - Ich würde die USA erraten, Hinweis: "fallen";) – SymbolixAU

+0

@allistaire, habe ich die Monate auf die Jahreszeiten basierend auf den OP-Mappings abgebildet. "Fall" war mein Beitrag, ha. – Jota

4

Ein bisschen Typisierung, aber der Code ist effizient

dt[MonthName %in% c("Jun","Jul","Aug"), Season := "Winter"] 
dt[MonthName %in% c("Dec","Jan","Feb"), Season := "Summer"] 
dt[MonthName %in% c("Sep","Oct","Nov"), Season := "Spring"] 
dt[is.na(MonthName), Season := "Autumn"] 

Hier bieten wir Ihnen Verweis auf eine Teilmenge der data.table

zuweisen ziehe ich diese auf eine Menge von verschachtelten ifelse s


Wenn Sie überprüfen möchten, ob ein Wert in einem Vektor ist, müssen Sie %in% verwenden. Siehe das unterschiedliche Verhalten von:

myVec <- c("a","b","c") 

"a" == myVec 
[1] TRUE FALSE FALSE 

"a" %in% myVec 
[1] TRUE 
+2

Wahrscheinlich effizienter sein, eine Nachschlagetabelle zu erstellen und einmal wie 'ref <- data.table (MonthName = month.abb [c (12,1: 11)], saison = rep (c (" Sommer "," Herbst ", "Winter", "Frühling"), jeweils = 3)); dt [ref, on = "MonthName"] ' – thelatemail

+0

@thelatemail - ähnlich wie Jotas Antwort, die eine +1 von mir bekam :) – SymbolixAU

+0

Whoops ... Seite wurde nicht aktualisiert, während ich den Kommentar schrieb. – thelatemail

Verwandte Themen