Commit | Line | Data |
---|---|---|
25b75559 | 1 | #' dateIndexToInteger |
3d69ff21 | 2 | #' |
102bcfda | 3 | #' Transform a (potential) date index into an integer (relative to data beginning). |
3d69ff21 BA |
4 | #' |
5 | #' @param index Date (or integer) index | |
102bcfda | 6 | #' @param data Object of class Data, output of \code{getData()} |
3d69ff21 BA |
7 | #' |
8 | #' @export | |
9 | dateIndexToInteger = function(index, data) | |
10 | { | |
102bcfda | 11 | # Works on integers too: trust input |
3d69ff21 BA |
12 | if (is.numeric(index)) |
13 | index = as.integer(index) | |
3d69ff21 | 14 | if (is.integer(index)) |
98e958ca BA |
15 | return (index) |
16 | ||
09cf9c19 | 17 | if (inherits(index, "Date") || is.character(index)) |
3d69ff21 | 18 | { |
72b9c501 BA |
19 | tryCatch(indexAsDate <- as.Date(index), |
20 | error=function(e) stop("Unrecognized index format")) | |
3d69ff21 | 21 | #TODO: tz arg to difftime ? |
44a9990b BA |
22 | integerIndex <- round( as.numeric( |
23 | difftime(indexAsDate, as.Date(data$getTime(1)[1])) ) ) + 1 | |
24 | if (integerIndex >= 1 && integerIndex <= data$getSize()) | |
25b75559 | 25 | return (integerIndex) |
3d69ff21 BA |
26 | stop("Date outside data range") |
27 | } | |
28 | stop("Unrecognized index format") | |
29 | } | |
30 | ||
25b75559 | 31 | #' integerIndexToDate |
09cf9c19 | 32 | #' |
102bcfda | 33 | #' Transform an integer index (relative to data beginning) into a date index. |
09cf9c19 | 34 | #' |
102bcfda | 35 | #' @inheritParams dateIndexToInteger |
09cf9c19 BA |
36 | #' |
37 | #' @export | |
38 | integerIndexToDate = function(index, data) | |
39 | { | |
102bcfda | 40 | # Works on dates too: trust input |
98e958ca BA |
41 | if (is.character(index)) |
42 | index = as.Date(index) | |
a66a84b5 | 43 | if (is(index,"Date")) |
98e958ca BA |
44 | return (index) |
45 | ||
09cf9c19 BA |
46 | index = index[1] |
47 | if (is.numeric(index)) | |
48 | index = as.integer(index) | |
49 | if (!is.integer(index)) | |
a66a84b5 | 50 | stop("'index' should be a date or integer") |
09cf9c19 BA |
51 | as.Date( data$getTime(index)[1] ) |
52 | } | |
53 | ||
25b75559 | 54 | #' getSimilarDaysIndices |
3d69ff21 | 55 | #' |
102bcfda BA |
56 | #' Find similar days indices in the past; at least same type of day in the week: |
57 | #' monday=tuesday=wednesday=thursday != friday != saturday != sunday. | |
3d69ff21 BA |
58 | #' |
59 | #' @param index Day index (numeric or date) | |
ee8b1b4e | 60 | #' @param data Reference dataset, object output of \code{getData} |
3d69ff21 | 61 | #' @param limit Maximum number of indices to return |
4e25de2c | 62 | #' @param same_season Should the indices correspond to day in same season? |
6774e53d | 63 | #' @param days_in Optional set to intersect with results (NULL to discard) |
3d69ff21 BA |
64 | #' |
65 | #' @export | |
638f27f4 BA |
66 | getSimilarDaysIndices = function(index, data, limit, same_season, |
67 | days_in=NULL, operational=TRUE) | |
3d69ff21 | 68 | { |
ee8b1b4e | 69 | index = dateIndexToInteger(index, data) |
3d69ff21 | 70 | |
ee8b1b4e | 71 | # Look for similar days (optionally in same season) |
3d69ff21 | 72 | days = c() |
ee8b1b4e BA |
73 | dt_ref = as.POSIXlt(data$getTime(index)[1]) #first date-time of current day |
74 | day_ref = dt_ref$wday #1=monday, ..., 6=saturday, 0=sunday | |
75 | month_ref = as.POSIXlt(data$getTime(index)[1])$mon+1 #month in 1...12 | |
c36568fa | 76 | i = index - 1 |
638f27f4 BA |
77 | if (!operational) |
78 | j = index + 1 | |
79 | while (length(days) < min( limit, ifelse(is.null(days_in),Inf,length(days_in)) )) | |
3d69ff21 | 80 | { |
dca259e4 BA |
81 | if (i < 1 && j > data$getSize()) |
82 | break | |
638f27f4 | 83 | if (i >= 1) |
ee8b1b4e | 84 | { |
638f27f4 BA |
85 | dt = as.POSIXlt(data$getTime(i)[1]) |
86 | if ((is.null(days_in) || i %in% days_in) && .isSameDay(dt$wday, day_ref)) | |
87 | { | |
88 | if (!same_season || .isSameSeason(dt$mon+1, month_ref)) | |
89 | days = c(days, i) | |
90 | } | |
91 | i = i - 1 | |
92 | } | |
93 | if (!operational && j <= data$getSize()) | |
94 | { | |
95 | dt = as.POSIXlt(data$getTime(j)[1]) | |
96 | if ((is.null(days_in) || j %in% days_in) && .isSameDay(dt$wday, day_ref)) | |
97 | { | |
98 | if (!same_season || .isSameSeason(dt$mon+1, month_ref)) | |
99 | days = c(days, j) | |
100 | } | |
101 | j = j + 1 | |
ee8b1b4e | 102 | } |
3d69ff21 | 103 | } |
a866acb3 BA |
104 | return ( days ) |
105 | } | |
3d69ff21 | 106 | |
ee8b1b4e BA |
107 | # isSameSeason |
108 | # | |
102bcfda | 109 | # Check if two months fall in the same "season" (defined by estimated pollution rate). |
ee8b1b4e | 110 | # |
102bcfda BA |
111 | # @param month Month index to test |
112 | # @param month_ref Month to compare to | |
ee8b1b4e BA |
113 | # |
114 | .isSameSeason = function(month, month_ref) | |
a866acb3 | 115 | { |
f71b975b BA |
116 | # if (month_ref == 3) #TODO: same as Bruno (but weird) |
117 | # return (month %in% c(2,3,4,9,10)) | |
ee8b1b4e | 118 | if (month_ref %in% c(11,12,1,2)) #~= mid-polluted |
a866acb3 | 119 | return (month %in% c(11,12,1,2)) |
ee8b1b4e | 120 | if (month_ref %in% c(3,4,9,10)) #~= high-polluted |
a866acb3 | 121 | return (month %in% c(3,4,9,10)) |
ee8b1b4e | 122 | return (month %in% c(5,6,7,8)) #~= non polluted |
3d69ff21 | 123 | } |
25b75559 | 124 | |
ee8b1b4e BA |
125 | # isSameDay |
126 | # | |
102bcfda | 127 | # Monday=Tuesday=Wednesday=Thursday ; Friday, Saturday, Sunday: specials. |
ee8b1b4e | 128 | # |
102bcfda BA |
129 | # @param day Day index to test |
130 | # @param day_ref Day index to compare to | |
ee8b1b4e BA |
131 | # |
132 | .isSameDay = function(day, day_ref) | |
133 | { | |
c36568fa BA |
134 | if (day_ref %in% 1:4) |
135 | return (day %in% 1:4) | |
ee8b1b4e BA |
136 | return (day == day_ref) |
137 | } | |
41196789 | 138 | |
689aa1d3 BA |
139 | # getNoNA2 |
140 | # | |
cf3bb001 | 141 | # Get indices in data of no-NA series preceded by no-NA, within [first,last] range. |
689aa1d3 BA |
142 | # |
143 | # @inheritParams dateIndexToInteger | |
144 | # @param first First index (included) | |
145 | # @param last Last index (included) | |
146 | # | |
41196789 BA |
147 | .getNoNA2 = function(data, first, last) |
148 | { | |
149 | (first:last)[ sapply(first:last, function(i) | |
cf3bb001 | 150 | !any( is.na(data$getSerie(i-1)) | is.na(data$getSerie(i)) ) |
41196789 BA |
151 | ) ] |
152 | } |