Attachment 'romanDates.R'
Download 1 #' Check Validity of Dates with Roman Numerial Month
2 #'
3 #' Check string is a valid date with Roman numerial month.
4 #' @param x A character string
5 #' @param sep Punctuation between day-month-year. Defaults to fullstop.
6 #' @param pad Whether days should be padded with leading 0s. Defaults to TRUE.
7 #' @return If the supplied string parses to Roman date, returns TRUE with the \code{"names"} attribute set to the date formatted with numerical month for later pocessing, if needed. If the the day is not correctly zero-padded, then FALSE is returned. If the date is invalid, then NA is returned.
8 #' @examples
9 #' isRomanDate("02.X.2018")
10 #' isRomanDate("3-V-2015", sep="-", pad=FALSE)
11 #' isRomanDate("21.IIII.2018") # invalid Roman number, FALSE returned
12 #' isRomanDate("31.II.2018") # invalid days in month, NA returned
13 #' @export
14 isRomanDate <- function(x, sep = '.', pad = TRUE)
15 {
16 if (length(x) > 1L)
17 message("argument 'x' has length > 1 and only the first element will be used")
18 x <- x[[1]]
19 day.pad <- sprintf("%02s", 1:9)
20 month.num <- sprintf("%02s", 1:12)
21 month.roman <- as.character(as.roman(month.num))
22 month.pattern <- paste(month.roman, collapse = '|')
23 date.pattern <- sprintf('[[:digit:]]{1,2}[%s](%s)[%s][[:digit:]]{4}', sep, month.pattern, sep)
24 result <- grepl(date.pattern, x, perl=TRUE)
25 if (result) {
26 dmy <- unlist(strsplit(x, sep, fixed=TRUE))
27 if (pad && as.numeric(dmy[1]) < 10 && !(dmy[1] %in% day.pad))
28 return(FALSE)
29 dmy[2] <- month.num[month.roman == dmy[2]]
30 dmy <- paste(dmy[3:1], collapse='-')
31 result <- as.character(as.Date(dmy, '%Y-%m-%d'))
32 if (!is.na(result)) {
33 n <- result
34 result <- TRUE
35 names(result) <- n
36 }
37 }
38 return(result)
39 }
40 #' Check Vector of Possible Roman Dates
41 #'
42 #' Strings to be checked supplied as a character vector, or frequency vector with the \code{"names"} attribute.
43 #' @param x A character vertor, or numerical vector with character strings supplied in the \code{"names"} attribute.
44 #' @param sorted Whether to sort the returned list. Defaults to TRUE.
45 #' @param sep Punctuation between day-month-year. Defaults to fullstop.
46 #' @param pad Whether days should be padded with leading 0s. Defaults to TRUE.
47 #' @return The function returns the same vector type as supplied. If a named frequency vector is supplied, the numerical frequencies are not altered. The character vector returned, either directly or as a \code{"names"} attribute, contains the the original strings appened with either "(?)" or "(??)". The former indicates the date is correct but the zero-padding of the day does not conform. The latter indicates the date is not valid (e.g., 31 days in a month with only 30 days).
48 #'
49 #' If sorted = TRUE, then dates sorted in ascending chronological order included dates that are valid but not zero-padded as requested. Invalid dates are placed at then end of the list.
50 #' @examples
51 #' rD.test <- 1:3
52 #' names(rD.test) <- c('03.VX.2018', '05.VII.2018', '9.VIII.2018')
53 #' romanDates(rD.test)
54 #' @export
55 romanDates <- function(x, sorted = TRUE, sep = '.', pad = TRUE) {
56 r <- list()
57 if (length(x) == 0)
58 return(list(x))
59 r$names <- x
60 if (is.numeric(x)) {
61 r$count <- x
62 r$names <- names(x)
63 }
64 r$date <- numeric()
65 r$pad <- logical()
66 r$order <- numeric()
67 for (i in r$names) {
68 r$date <- append(r$date, NA)
69 r$pad <- append(r$pad, FALSE)
70 ln = length(r$date)
71 valid <- isRomanDate(i, sep = sep, pad = pad)
72 if (is.na(valid))
73 next()
74 if (valid) {
75 r$date[ln] <- names(valid)
76 r$pad[ln] <- TRUE
77 next()
78 }
79 valid <- isRomanDate(i, sep = sep, pad = !pad)
80 if (valid)
81 r$date[ln] <- names(valid)
82 }
83 r$order <- order(r$date)
84 r$names[!(is.na(r$date) | r$pad)] <- sprintf('%s (?)', r$names[!(is.na(r$date) | r$pad)])
85 r$names[is.na(r$date)] <- sprintf('%s (??)', r$names[is.na(r$date)])
86 if (is.numeric(x)) {
87 result <- r$count
88 names(result) <- r$names
89 } else result <- r$names
90 if (sorted)
91 result <- result[r$order]
92 return(result)
93 }
You are not allowed to attach a file to this page.