I have a zoo object in R that has daily data and is missing the weekends. When I try to run some functions (for example ar() ) on the object i get the error:
mkt.ar <- ar(zoo_object)
Error in na.fail.default(as.ts(x)) : missing values in object
If I do:
mkt.ar <- ar(zoo_object, na.action=na.omit)
Error in na.omit.ts(as.ts(x)) : time series contains internal NAs
This makes sense since when zoo tries to convert things to ts, the weekends are inherently missing. Other than converting things to a vector using coredata(zoo_object) and running ar() on that, is there a way to tell R to skip the missing data?
Thanks
I gather that every day is represented in your data including weekdays and weekends but the days for which no data is present are NA (as opposed to not being present at all). In the future please provide some test data for better clarity.
Aside from your solution, if you have enough data you could perform an ar on weekly data only by extracting the last non-missing value on or before Friday:
library(zoo)
# test data
library(chron) # is.weekend
z <- zoo(100:130, as.Date("2000-01-01") + 0:30)
z[is.weekend(time(z))] <- NA
# extract Fridays
zfri <- na.locf(z)[format(time(z), "%w") == 5]
(If there are no missing Fridays it can be shortened by replacing na.locf(z) with z.)
Another possibility is to use 1, 2, ... for the times but give them names in which case you could always find out what date a point belongs to by checking the name of its time.
z1 <- na.omit(z)
time(z1) <- setNames(seq_along(z1), time(z1))
Simplest method will be convert the ZOO object into data.frame object by
for example (z1 is zoo object):
dz1<-data.frame(na.omit(z1))
then convert it to time series object.
ts(dz1, frequency=5)
Related
I am new to R and need to use the function getnfac from the PANICr package. And it seems that the function only takes an xts object as its first argument. However, after I went through some reading I still don't understand what an xts object is. Could anyone please tell me how I can convert a matrix into an xts object?
Below I use return matrix as the first argument. Therefore I just need to convert return to an xts object.
getnfac(return,143,"BIC3")
Error in getnfac(return, 143, "BIC3") :
x must be an xts object so lags and differences are taken properly
xts is an extensible time series object, essentially a regular ts object (or more correctly a zoo object) with some bits added.
The 'extensible' part of the name refers to how you can add attributes of your own choice.
While a matrix can be converted into a multivariate time series quite easily
m <- matrix(1:16, 4)
m.ts <- ts(m)
index(m.ts)
An xts requires its index (a vector describing at what time each sample was taken) to be in a date or time format
library(xts)
m <- matrix(1:16, 4)
d <- as.Date(1:nrow(m))
m.xts <- xts(m, order.by=d)
index(m.xts)
If your data is sampled at evenly spaced intervals a dummy index like the one above is probably ok. If not, you'll need to supply a vector corresponding to the sampling times.
In my opinion, the first argument to the getnfac() function should be matrix containing the data.
In addition to the above answers,
You can convert matrix format using coredata() about xts object.
I want to create a Time Series data frame by doing this:
x <- xts(data$length,data$Time.Elapsed)
Then, I got a warning message:
Error in xts(data$length, data$Time.Elapsed) :
order.by requires an appropriate time-based object
So, I was thinking the problem is my "Time.Elapsed" is numeric data. Then I want to convert the data type of "Time.Elapsed", how can I achieve that?
>data$Time Elapsed
Time Elapsed
0
1
2
3
4
5
I want to create a time series data frame, so I need to have a time-based object in R. Here, "Time Elapsed" is a numeric variable (those numbers represent seconds); how can I convert it to time type "seconds"? I searched the Data-time conversion function, like: as.POSIX* {base} But I don't think this function suits my case. Anyone can help me about this? Thank you very much!
I believe you're not going low-level enough on this. xts provides some convenience functions to help determine if you can convert something to xts or not.
xtsible(data) #Will probably tell you it fails with your current setup.
xts builds on zoo, and zoo is a bit more flexible though harder to work with.
library(zoo)
zooData <- zoo(data$length, data$Time.Elapsed)
xtsible(zooData) #Will probably tell you it's ok, but probably doesn't matter since
#most/all of xts's functions work on zoo objects.
xtsData <- xts(zooData)
require(lubridate)
x <- as.POSIXct(strptime(data$Time.Elapsed, format = "%S"))
as.duration(x)
This should do the trick.
I assumed the following code
date = as.Date('2015-05-30')
timeseries = xts()
timeseries[date] = 1
should assign the value of 1 to a date '2015-05-30'. However, it gives me an error
Error in xts(rep(NA, length(index(x))), index(x)) :
order.by requires an appropriate time-based object
What is the proper way to assign the value to an empty xts object?
Thanks,
Vladimir
I think you misunderstand the purpose of the [<-.xts function. You're asking to replace the value at date "2015-05-30" with 1, but your xts object has no data, so there's nothing to replace. What are you actually trying to accomplish?
If you want to insert, you should call rbind(xts(1, as.Date('2015-05-30')), timeseries).
And you should heed Mike Wise's wise advice: it is very inefficient to grow objects like this.
Try something like this:
d1 <- rep(1,21)
d2 <- seq(as.Date("2001-01-01",tz="GMT"),as.Date("2021-01-01",tz="GMT"),length.out=21)
xtsdat <- as.xts(d1,d2)
If you need to build it up row by row, then build the individual vectors that way and form the xts at the end.
I have an xts object and I am trying to use period.apply with a function that would return more than one value for each non-overlapping period. For example: I run a regression and would like to return the residuals for each non-overlapping period and thus my function returns all the dates from that period along with the residual at each particular date. It currently seems that xts does not support this behavior. Is this correct? Is there a work around?
> df <- data.frame(x=rnorm(31)+10, y=rnorm(31)+10)
> xts.data <- xts(df, order.by=as.Date(13514:(13544),origin="1970-01-01"))
> f <- function(d) {as.numeric(coredata(d[,"x"]))}
> period.apply(xts.data, INDEX=endpoints(xts.data,"weeks"), FUN=f)
Error in coredata.xts(x) : currently unsupported data type
It just occurred to me that the problem is likely that each non-overlapping period doesn't have the same number of observations, so there's no way to easily create a matrix-like structure.
Use something like this instead, and notice how each list element isn't the same length:
lapply(split(xts.data,"weeks"), f)
To illustrate how period.apply can return more than one column per period:
period.apply(xts.data, endpoints(xts.data,"weeks"), range)
period.apply(xts.data, endpoints(xts.data,"weeks"), colMeans)
I have two data.frames in R, each indexed by date. One is coarser than the other and I would like to compare the data only along the coarser timescale.
To be more concrete let's say one data.frame has time points DF1[a,b,c,...,x,y,z] and the other only has DF2[f,p,t], where p=="July 19, 1917". I wish to compare DF1[f,p,t] to DF2[f,p,t].
This isn't syntactic but I want to do for each $i { DF_combined <- df1[$i] . df2[$i] if exists(df1[$i]); }. In other words, make a new data.frame that only contains every shared observation day.
I hope the question is clear. I've been looking at other SO answers for a couple of hours and haven't found one that covers what I'm trying to do yet. Thanks in advance.
Merge your data.frames, then do whatever operations you want.
# assume the frequency of x > frequency of y (i.e. y is "coarse")
merge(x, y, by="row.names", all.y=TRUE) # dates are in row.names
merge(x, y, by="date", all.y=TRUE) # dates are in "date" column
Since you have a time-series, I would suggest you use a time-series class instead of a data.frame. I recommend xts/zoo. Here's how you would do this with xts:
merge(x, y, join="right")
Here's the solution to my problem, from start to finish.
Problem: Given records from my broker (not evenly spaced in time), put the time series of my net worth next to a time series of the S&P, for comparison in R.
Answer:
#get S&P data
require(quantmod)
getSymbols("^GSPC", from="2004-01-01", src="yahoo")
head(GSPC)
GSPC.Open GSPC.High GSPC.Low GSPC.Close GSPC.Volume GSPC.Adjusted
2004-01-02 1111.92 1118.85 1105.08 1108.48 1153200000 1108.48
2004-01-05 1108.48 1122.22 1108.48 1122.22 1578200000 1122.22
2004-01-06 1122.22 1124.46 1118.44 1123.67 1494500000 1123.67
Notice that there is no header over the dates. That's because time-series data types embed the time-value as an ordering index. (class(GSPC) = [1] "xts" "zoo" where zoo is a data type totally ordered by an index, and xts is a time series data-type that tolerates more than the restrictive native ts data type tolerates.)
#coerce the .csv from my broker into a time-series data type as well
MyNetWorth <- read.csv("/home/joey/Desktop/Historical_NAV.csv")
require(xts)
MyNetWorth <- as.xts( MyNetWorth,
order.by= as.Date(MyNetWorth$TradeDate, format="%m/%d/%Y") )
In the date format there is a big difference between %Y ('87) and %y (1987), as well as between %m – months and %M – minutes. My broker wrote 10/23/2009.
So did I do it right?
> class(MyNetWorth)
[1] "xts" "zoo"
Yessss.
Finally, #Joshua Ulrich's advice does the kind of merge I want:
comparison <- merge(GSPC$GSPC.Adjusted, MyNetWorth$NetAssets, join="right")
The right join compares the dates only at the coarser scale (my data is always coarser than Yahoo's).
Last of all, to plot the results:
plot( as.zoo(comparison) , screens=c(1,1), col=c("red", "#333333") )
Many thanks to all the people who wrote all this open source software — and especially to those who wrote vignettes!