Question

I have the following df:

> head(giftByDay)
    giftDate    gift   yr mon day
1 2009-07-01  100.00 2009   7   1
2 2009-07-03  300.00 2009   7   3
3 2009-07-06  470.00 2009   7   6
4 2009-07-07 7436.66 2009   7   7
5 2009-07-09   50.00 2009   7   9
6 2009-07-11   25.00 2009   7  11

It has 3 years of data (fiscal year ends June 30) and I'm trying to put it all 3 in one plot as 3 separate lines to compare year over year performance. Also I'm trying to put dollars on the y-axis and MM-DD on the x-axis.

I break it into 3 chunks based on year:

> yr2009 <- subset(giftByDay, giftByDay$giftDate >= "2009-07-01" & giftByDay$giftDate < "2010-07-01")
> yr2010 <- subset(giftByDay, giftByDay$giftDate >= "2010-07-01" & giftByDay$giftDate < "2011-07-01")
> yr2011 <- subset(giftByDay, giftByDay$giftDate >= "2011-07-01" & giftByDay$giftDate < "2012-07-01")

Next I create zoo objects for plotting:

> yr2009$d2 <- format(as.Date(yr2009$giftDate), "%m-%d")
> x1 <- zoo(yr2009$gift, yr2009$d2)
> yr2010$d2 <- format(as.Date(yr2010$giftDate), "%m-%d")
> x2 <- zoo(yr2010$gift, x2.Date)
> yr2011$d2 <- format(as.Date(yr2011$giftDate), "%m-%d")
> x3 <- zoo(yr2011$gift, x3.Date)

The problems start when I try to actually plot it:

> plot(x1, type="l", col=1)
Error in plot.window(...) : need finite 'xlim' values
In addition: Warning messages:
1: In xy.coords(x, y, xlabel, ylabel, log) : NAs introduced by coercion
2: In min(x) : no non-missing arguments to min; returning Inf
3: In max(x) : no non-missing arguments to max; returning -Inf
> points(x2, type="l", col=2)
Warning message:
In xy.coords(x, y) : NAs introduced by coercion
> points(x3, type="l", col=3)
Warning message:
In xy.coords(x, y) : NAs introduced by coercion

There's actually stuff in the objects:

> head(x1)
   01-01    01-04    01-05    01-08    01-11    01-13 
    15.0    125.0   1000.0   6350.0    200.0 291281.1 

But I can't figure out why it won't plot. Any suggestions?

EDIT:

> giftByDayList <- split(as.xts(giftByDay), "years")
Error in as.POSIXlt.character(x, tz, ...) : 
  character string is not in a standard unambiguous format

> class(giftByDay$giftDate)
[1] "character"

I'm not sure what's causing this error.

EDIT 2:

> gbd <- zoo(giftByDay)
> gbd <- as.xts(gbd)
Error in xts(coredata(x), order.by = order.by, frequency = frequency,  : 
  order.by requires an appropriate time-based object
> giftByDayList <- split(as.xts(gbd), "years")
Error in xts(coredata(x), order.by = order.by, frequency = frequency,  : 
  order.by requires an appropriate time-based object

EDIT 3:

> giftByDayList <- split(xts(giftByDay[,-1],as.Date(giftByDay$giftDate)), "years")
> giftByDayList <- lapply(giftByDayList, toyear, 2011)
Error in `index<-.xts`(`*tmp*`, value = list(sec = c(0, 0, 0, 0, 0, 0,  : 
  unsupported ‘index’ index type of class ‘POSIXt’unsupported ‘index’ index type of class ‘POSIXlt’

> str(giftByDayList )
List of 3
 $ :An ‘xts’ object from 2009-07-01 to 2009-12-31 containing:
  Data: num [1:89, 1:4] 100 300 470 7437 50 ...
 - attr(*, "dimnames")=List of 2
  ..$ : NULL
  ..$ : chr [1:4] "gift" "yr" "mon" "day"
  Indexed by objects of class: [Date] TZ: 
  xts Attributes:  
 NULL
 $ :An ‘xts’ object from 2010-01-01 to 2010-12-31 containing:
  Data: num [1:213, 1:4] 15 125 1000 6350 200 ...
 - attr(*, "dimnames")=List of 2
  ..$ : NULL
  ..$ : chr [1:4] "gift" "yr" "mon" "day"
  Indexed by objects of class: [Date] TZ: 
  xts Attributes:  
 NULL
 $ :An ‘xts’ object from 2011-01-02 to 2011-10-26 containing:
  Data: num [1:189, 1:4] 1500 235 1000 18154 10 ...
 - attr(*, "dimnames")=List of 2
  ..$ : NULL
  ..$ : chr [1:4] "gift" "yr" "mon" "day"
  Indexed by objects of class: [Date] TZ: 
  xts Attributes:  
 NULL
> 
Was it helpful?

Solution

1) data.frame solution. Try this. We set up some test data and then calculate the fiscal year and rebase each date in the transform statement. Finally we plot the gift vs. rebased date by fiscalyear. Note that its really just two statements, one for the transform and one for the plot.

## set up test data

giftDate <- seq(as.Date("2009-07-01"), length = 36, by = "month")
giftByDay <- data.frame(giftDate, gift = 1:36,
    yr = as.numeric(format(giftDate, "%Y")),
    mon = as.numeric(format(giftDate, "%m")),
    day = as.numeric(format(giftDate, "%d")))

## now that we have test data, calculate fiscalyear, rebase each date to 1999-2000
## and plot

giftByDay <- transform(giftByDay, fiscalyear = yr + (mon > 6),
    Date = as.Date(paste(2000 - (mon > 6), mon, day, sep = "-")))

library(lattice)
xyplot(gift ~ Date,  giftByDay, group = fiscalyear, type = "o", auto.key = TRUE)

EDIT:

Added zoo solution below.

2) zoo solution. In this case the solution is not simpler than just using a data frame although it might have an advantage if the particular form of z can be used for other calculations:

library(zoo)
library(lattice)

giftByDay <- transform(giftByDay, fiscalyear = yr + (mon > 6))

z <- read.zoo(giftByDay[2:6], index = 2:4, split = 5, FUN = function(y, m, d)
        as.Date(paste(2000 - (m > 6), m, d, sep = "-")))
xyplot(z, screen = 1, col = 1:3, type = "o", auto.key = TRUE, ylab = "Gift")

Here is what the zoo object z looks like:

> z
           2010 2011 2012
1999-07-01    1   13   25
1999-08-01    2   14   26
1999-09-01    3   15   27
1999-10-01    4   16   28
1999-11-01    5   17   29
1999-12-01    6   18   30
2000-01-01    7   19   31
2000-02-01    8   20   32
2000-03-01    9   21   33
2000-04-01   10   22   34
2000-05-01   11   23   35
2000-06-01   12   24   36

OTHER TIPS

This answer is a modified version of my answer to Related to xts/time-series and plot questions... on R-help.

You can do this by converting each index value to have the same year. The toyear function below does this.

toyear <- function(x, year) {
  # get year of last obs
  xyear <- .indexyear(last(x))+1900
  # get index and convert to POSIXlt
  ind <- as.POSIXlt(index(x))
  # set index year to desired value
  ind$year <- year-1900
  index(x) <- ind
  # label column with year of last obs
  colnames(x) <- paste(colnames(x),xyear,sep=".")
  x
}

# split data into a list of xts objects by year
giftByDayList <- split(xts(giftByDay[,-1],as.Date(giftByDay$giftDate)), "years")
# convert each list element to be "2011"
giftByDayList <- lapply(giftByDayList, toyear, 2011)
# merge all list elements into one object
giftByDayByYear <- as.zoo(do.call(merge, giftByDayList))
# plot on one "screen"
plot(giftByDayByYear, screens=1, col=rainbow(ncol(giftByDayByYear)))
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top