How to sort string date in marklogic? - xquery

we have to sort year and month combination in marklogic
Ex.
"2018 April",
"2018 Dec",
"2018 Feb",
"2018 Nov"
its sorting according to alphabetic order, but i want to sort on the basis of month and year.

You'll have to normalize the values, that for sure. You could normalize to:
xs:date (as Martin suggested as well)
or xs:gYearMonth
You could do so either on ingest, or at runtime.
Doing so on ingest allows leveraging MarkLogic range indexes to support the sorting, using for instance cts:index-order in combination with cts:search.
At runtime you could cast to xs:date or xs:gYearMonth too (after normalizing on the fly), but you can also just order on the normalized strings directly, without casting. Sorting and normalizing at runtime will perform worse though, and not scale well.
Regarding normalizing itself, you can use the string manipulation described by Martin, but you can also make use of the MarkLogic function xdmp:parse-dateTime, for instance something like this:
xs:gYearMonth(xdmp:parse-dateTime("[Y] [Mn]", "2018 Jan"))
It takes additional parameters to indicate language and such too.
HTH!

You can certainly try to convert the format to an xs:date and use order by e.g.
let $seq := ("2018 Apr", "2018 Dec", "2018 Feb", "2018 Nov"),
$month-order := ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec')
for $date in $seq
order by xs:date(
substring($date, 1, 4)
|| '-'
||format-number(index-of($month-order, substring($date, 6, 3)), '00')
|| '-01')
return $date
gives
"2018 Feb"
"2018 Apr"
"2018 Nov"
"2018 Dec"
Note that I simplified the task by assuming a consistent three letter month name. And I am not familiar with the particular XQuery processor Marklogic you use whether it has some custom date parsing functions that make the task easier, I simply used XQuery 3.1 functions and expressions. Working demo at https://xqueryfiddle.liberty-development.net/948Fn59

Related

Determine the Quarter from a date

Let say I have date as follows:
Date = as.Date('2020-11-30')
Now I want to determine the quarter for this date, So I can use the zoo package
library(zoo)
as.yearqtr(Date). ### [1] "2020 Q4"
However I want to determine the quarter with respect to a date, say
Date1 = as.Date("2020-05-31")
So with respect to this date, the quarter of Date should be Q2.
Is there any way to set up the base in the quarter calculation?
Any pointer will be highly appreciated.
Thanks,
if we want to extract the quarter, use format
format(as.yearqtr(Date1), 'Q%q')
[1] "Q2"
Or if it is based on difference, try
paste0("Q", (as.yearqtr(Date) - as.yearqtr(Date1)) * 4)
[1] "Q2"

How do I express an ISO8601 date as Day-Month?

I'm plotting time series data that has an ISO8601 variable as the x-axis; however, having the labels as ISO8601 isn't very readable. What is the best way to retain the ISO8601 variable but display the labels as Day Month (i.e. 28 Jun)?
Here is what I currently have:
format(as.Date("2020-06-28"),"%d %b"))
But that means they now display in order like:
c("03 May","04 Jun", "06 May","07 Jun")
How can I get them to arrange in Date order?

How to input quarterly data in R

I have panel of quarterly data which looks like this:
x <- c("Q1 2013","Q2 2013", "Q3 2013", "Q4 2013")
How can I be able to properly input this data into r as quarterly time series date so I would be able to perform analysis on it?
I tried to use yearqtr from zoo package but all I receive is NA.
as.Date(as.yearqtr(x, format = "Q%q /%yyyy"))
This could be because of the space between Q1 and 2013, I'm open to change my format if I have to but I'm not even sure what format would work in R. Should I change my columns to 1.2013, 2.2013, ... or this would also not be recognized as a date format by R? And how am I gonna be able to change them when I have a repeated sample of quarterly date in this format: Q1 2013, etc.
This should solve your problem:
as.yearqtr(format(x), "Q%q %Y")
This is the output:
# [1] "2013 Q1" "2013 Q2" "2013 Q3" "2013 Q4"
You can make it as dates meanwhile:
as.Date(as.yearqtr(format(x), "Q%q %Y"))
And the output would be:
# [1] "2013-01-01" "2013-04-01" "2013-07-01" "2013-10-01"

Transforming Calendar Quarter to Financial Quarter

I am working with a dateframe (INPUT) that contains number the of transaction of a product per calendar quarter. The first column (DATE) contains the calendar quarter in this format "2016 Q2". I would like to transform this date into the a financial quarter format such as "2016/17 Q1". The financial year start in the 1st April.
I came up with the following code which does the job, but I was wondering if there is a formula or a neater code that I could use.
INPUT$FY_Date=character(nrow(INPUT))
for (i in 1:nrow(INPUT)) {
INPUT$FY_Date[i]= if(substr(INPUT$DATE[i],7,7)==1) paste(as.numeric(substr(INPUT$DATE[i],1,4))-1,"/",substr(INPUT$DATE[i],3,4)," Q4",sep="") else
paste(substr(INPUT$DATE[i],1,4),"/", formatC(as.numeric(substr(INPUT$DATE[i],3,4))+1,width=2,format="d",flag=0)," Q",as.numeric(substr(INPUT$DATE[i],7,7))-1,sep="")
}
I could not find any previous related posts so I would appreciate any guidance.
Using the "yearqtr" class defined in zoo we can do it in two lines of code.
Convert to "yearqtr". The "yearqtr" class uses an internal representation of year + (qtr-1)/4 where qtr is 1, 2, 3 or 4 so adding 3/4 will shift it to the year-end year and fiscal quarter. Then in the final line of code as.integer will extract the year-end year. format function can be used to get the rest where %y means 2 digit year and %q means quarter.
library(zoo)
# test input
yq <- c("2016 Q2", "2016 Q3", "2016 Q4", "2017 Q1")
fyq <- as.yearqtr(yq, format = "%Y Q%q") + 3/4
paste0(as.integer(fyq) - 1, format(fyq, "/%y Q%q"))
giving:
[1] "2016/17 Q1" "2016/17 Q2" "2016/17 Q3" "2016/17 Q4"
Note that if you don't need the specific format shown in the question you could just use format(fyq) in place of the last line or maybe format(fyq, "%Y Q%q").
Update: Minor code improvements.

R merging Quarterly data with first date of quarter as the index

I can generate quarterly OHLC date from a daily time series:
library(quantmod)
getSymbols("SPY", from="2000-01-01", to=Sys.Date())
tail(SPY)
dfQ <- to.quarterly(SPY[,6])
tail(dfQ)
I can also generate the quarterly mean:
dfmean1 <- apply.quarterly(xts(SPY[,6]), FUN = mean)
tail(dfmean1)
However I am having problems merging the two, with an index showing the first date of the quarter (rather than the last date of the quarter).
Thank you for your help
I think you have two questions here. The first is how to have a mean column in OHLC quarterly data. The second is how to have datestamps for the start of each quarter, instead of "last" datestamps. The xts/quantmod packages assume you want "last" datestamps, so go with the flow, and just replace the datestamps at the end.
To have mean with OHLC I've found it best just to do the OHLC calculation myself. So instead of passing mean to apply.quarterly(), do this:
bars = apply.quarterly(xts(SPY[,6]), FUN = function(x){
d=coredata(x);
c(first(d),max(d),min(d),last(d),mean(d))
} )
colnames(bars)=c("open","high","low","close","mean")
This gives:
...
2013-09-30 159.71 171.28 159.56 167.10 165.9822
2013-12-31 168.43 184.69 164.59 184.69 176.1416
2014-01-08 182.92 183.52 182.36 183.52 183.0340
Then to fix the datestamps:
index(bars) = as.Date(as.yearqtr(index(bars)))
To understand that, start by looking at index(bars), then look at as.yearqtr(index(bars)), which gives:
[1] "2000 Q1" "2000 Q2" "2000 Q3" ...
... "2013 Q3" "2013 Q4" "2014 Q1"
Then, as luck would have it, as.Date() gives you the datestamp of the start of each quarter.
The final bit is to assign the new index back to the bars object with index(bars) = ... (or index(bars) <- ... if you prefer).
By the way, there is also a indexAt="lastof" or indexAt="firstof" parameter you could give to to.quarterly(). Experiment with this, but in my tests it was not quite useful enough.

Resources