简体   繁体   中英

Reorder factor levels that are dates but only month and year in R

I'm using ggvis stacked barplots to create a graph where the x-axis is a time series of dates and the y-axis are frequencies.

The dates however, are in the format "Apr 2015" ie months and years.

In ggvis , this means that I have to make the dates in my dataframe factors.

I'm having trouble converting these month-year dates into factors that are ordered by their date. Instead, I get this order "Apr 2015, Jun 2015, May 2015"

This is my code:

selecteddates <- with(dailyIndMelt, dailyIndMelt[date >= as.Date(input$monthlydateInd[1]) & date <= as.Date(input$monthlydateInd[2]),])
selecteddates <- aggregate(selecteddates[,3],by=list(selecteddates$variable,substr(selecteddates$date,1,7)),sum)
colnames(selecteddates) <- c("industry", "date", "vacancyno")
selecteddates$date <- as.Date(paste(selecteddates$date,"-28",sep=""))
selecteddates <- selecteddates[order(as.Date(selecteddates$date)),]
selecteddates$date <- format(selecteddates$date, "%m %Y")
selecteddates$date <- factor(selecteddates$date)
levels(selecteddates$date) <- levels(selecteddates$date)[order(as.Date(levels(selecteddates$date), format="%m %Y"))]
levels(selecteddates)

To get the levels in the order you want, you can feed the desired order to the levels argument of factor . For example:

selecteddates$date <- factor(selecteddates$date, 
                             levels=paste(month.abb, rep(2014:2015, each=12)))

month.abb is a built-in vector of month abbreviations. The paste function pastes together the month abbreviations and the year values, so you get the correct ordering. I used years 2014 and 2015 for illustration. Just change that to whatever years appear in your data.

Here's the paste statement on its own for illustration:

paste(month.abb, rep(2014:2015, each=12))

 [1] "Jan 2014" "Feb 2014" "Mar 2014" "Apr 2014" "May 2014" "Jun 2014" "Jul 2014" "Aug 2014"
 [9] "Sep 2014" "Oct 2014" "Nov 2014" "Dec 2014" "Jan 2015" "Feb 2015" "Mar 2015" "Apr 2015"
[17] "May 2015" "Jun 2015" "Jul 2015" "Aug 2015" "Sep 2015" "Oct 2015" "Nov 2015" "Dec 2015"

Ideally, you can get the desired years programmatically, directly from your data. If your dates start out in a date format, you can do something analogous to this:

library(lubridate) # For year function

# Fake date data
dates = seq(as.Date("2010-01-15"), as.Date("2015-01-15"), by="1 day")

# Extract the years from the dates and use them to create the month-year levels
levels = paste(month.abb, rep(sort(unique(year(dates))), each=12))

In the code above, the sort ensures the years are in order, even if the dates are out of order.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM