#r #dataframe #date #dplyr #missing-data
Вопрос:
Скажем, у меня есть набор данных.
date lt;- c("2004-02-01", "2004-03-05", "2004-08-09", "2004-08-13", "2004-10-20", "2004-11-02", "2008-01-05", "2008-02-03", "2008-08-09", "2008-11-04", "2012-01-05", "2012-02-03", "2012-08-09", "2012-10-04", "2012-10-04", "2012-10-31", "2012-11-04") date lt;- ymd(date) name lt;- c("Joe", "Joe", "Joe", "Joe", "Joe", "Joe", "Larry", "Larry", "Larry", "Larry", "Jeff", "Jeff", "Jeff", "Jeff", "Jeff", "Jeff", "Jeff") hits lt;- c(5, 4, 10, 9, 15, 1, 13, 22, 9, 11, 15, 17, 10, 3, 4, 2, 33) df lt;- data.frame(date, name, hits)
Я хочу сделать 7-дневные задержки по времени для каждого наблюдения. Чтобы сделать это, мне придется немного реструктурировать набор данных.
Я хочу добавить семь дней после каждой даты для каждого имени, но количество просмотров будет равно 0. Я надеюсь получить набор данных, подобный следующему (для Джо):
date name hits 2004-02-01 Joe 5 2004-02-02 Joe 0 2004-02-03 Joe 0 2004-02-04 Joe 0 2004-02-05 Joe 0 2004-02-06 Joe 0 2004-02-07 Joe 0 2004-02-08 Joe 0 2004-03-05 Joe 4 2004-03-06 Joe 0 2004-03-07 Joe 0 2004-03-08 Joe 0 2004-03-09 Joe 0 2004-03-10 Joe 0 2004-03-11 Joe 0 2004-03-12 Joe 0 2004-08-09 Joe 10 2004-08-10 Joe 0 2004-08-11 Joe 0 2004-08-12 Joe 0 2004-08-13 Joe 9 2004-08-14 Joe 0 2004-08-15 Joe 0 2004-08-16 Joe 0 2004-08-17 Joe 0 2004-08-18 Joe 0 2004-08-19 Joe 0 2004-08-20 Joe 0 2004-10-20 Joe 15 2004-10-21 Joe 0 2004-10-22 Joe 0 2004-10-23 Joe 0 2004-10-24 Joe 0 2004-10-25 Joe 0 2004-10-26 Joe 0 2004-10-27 Joe 0 2004-11-02 Joe 1 2004-11-03 Joe 0 2004-11-04 Joe 0 2004-11-05 Joe 0 2004-11-06 Joe 0 2004-11-07 Joe 0 2004-11-08 Joe 0 2004-11-09 Joe 0
Есть ли быстрый способ сделать это с помощью dplyr
?
Ответ №1:
Эту dplyr::summarise
функцию можно использовать для добавления строк в течение следующих 7 дней для каждой комбинации name
и date
:
library(tidyverse) ndays=7 df.filled = df %gt;% mutate(date = as.Date(date)) %gt;% arrange(name, date) %gt;% group_by(name, date, hits) %gt;% summarise(date = date 0:ndays, hits = c(hits, rep(0, ndays))) %gt;% ungroup() df.filled %gt;% filter(name=="Joe") %gt;% print(n=Inf) #gt; # A tibble: 48 × 3 #gt; name date hits #gt; lt;chrgt; lt;dategt; lt;dblgt; #gt; 1 Joe 2004-02-01 5 #gt; 2 Joe 2004-02-02 0 #gt; 3 Joe 2004-02-03 0 #gt; 4 Joe 2004-02-04 0 #gt; 5 Joe 2004-02-05 0 #gt; 6 Joe 2004-02-06 0 #gt; 7 Joe 2004-02-07 0 #gt; 8 Joe 2004-02-08 0 #gt; 9 Joe 2004-03-05 4 #gt; 10 Joe 2004-03-06 0 #gt; 11 Joe 2004-03-07 0 #gt; 12 Joe 2004-03-08 0 #gt; 13 Joe 2004-03-09 0 #gt; 14 Joe 2004-03-10 0 #gt; 15 Joe 2004-03-11 0 #gt; 16 Joe 2004-03-12 0 #gt; 17 Joe 2004-08-09 10 #gt; 18 Joe 2004-08-10 0 #gt; 19 Joe 2004-08-11 0 #gt; 20 Joe 2004-08-12 0 #gt; 21 Joe 2004-08-13 0 #gt; 22 Joe 2004-08-14 0 #gt; 23 Joe 2004-08-15 0 #gt; 24 Joe 2004-08-16 0 #gt; 25 Joe 2004-08-13 9 #gt; 26 Joe 2004-08-14 0 #gt; 27 Joe 2004-08-15 0 #gt; 28 Joe 2004-08-16 0 #gt; 29 Joe 2004-08-17 0 #gt; 30 Joe 2004-08-18 0 #gt; 31 Joe 2004-08-19 0 #gt; 32 Joe 2004-08-20 0 #gt; 33 Joe 2004-10-20 15 #gt; 34 Joe 2004-10-21 0 #gt; 35 Joe 2004-10-22 0 #gt; 36 Joe 2004-10-23 0 #gt; 37 Joe 2004-10-24 0 #gt; 38 Joe 2004-10-25 0 #gt; 39 Joe 2004-10-26 0 #gt; 40 Joe 2004-10-27 0 #gt; 41 Joe 2004-11-02 1 #gt; 42 Joe 2004-11-03 0 #gt; 43 Joe 2004-11-04 0 #gt; 44 Joe 2004-11-05 0 #gt; 45 Joe 2004-11-06 0 #gt; 46 Joe 2004-11-07 0 #gt; 47 Joe 2004-11-08 0 #gt; 48 Joe 2004-11-09 0
Обратите внимание, однако, что с помощью приведенного выше кода вы можете получить повторяющиеся даты, если у данного name
есть две даты с интервалом менее 7 дней. Таким образом, вероятно, безопаснее сделать следующее: в приведенном ниже коде мы заполняем каждую дату с первого по последний 7 дней для каждого name
. Затем мы соединяем это обратно с исходными данными, чтобы заполнить даты, которые отличны от нуля hits
.
df$date = as.Date(df$date) df.filled2 = df %gt;% group_by(name) %gt;% summarise(date = seq(min(date), max(date) 7,"1 day")) %gt;% left_join(df) %gt;% mutate(hits=replace_na(hits, 0)) df.filled2 %gt;% filter(name=="Joe") %gt;% print(n=Inf) #gt; # A tibble: 283 × 3 #gt; # Groups: name [1] #gt; name date hits #gt; lt;chrgt; lt;dategt; lt;dblgt; #gt; 1 Joe 2004-02-01 5 #gt; 2 Joe 2004-02-02 0 #gt; 3 Joe 2004-02-03 0 #gt; 4 Joe 2004-02-04 0 #gt; 5 Joe 2004-02-05 0 #gt; 6 Joe 2004-02-06 0 #gt; 7 Joe 2004-02-07 0 #gt; 8 Joe 2004-02-08 0 #gt; 9 Joe 2004-02-09 0 #gt; 10 Joe 2004-02-10 0 #gt; 11 Joe 2004-02-11 0 #gt; 12 Joe 2004-02-12 0 #gt; 13 Joe 2004-02-13 0 #gt; 14 Joe 2004-02-14 0 #gt; 15 Joe 2004-02-15 0 #gt; 16 Joe 2004-02-16 0 #gt; 17 Joe 2004-02-17 0 #gt; 18 Joe 2004-02-18 0 #gt; 19 Joe 2004-02-19 0 #gt; 20 Joe 2004-02-20 0 #gt; 21 Joe 2004-02-21 0 #gt; 22 Joe 2004-02-22 0 #gt; 23 Joe 2004-02-23 0 #gt; 24 Joe 2004-02-24 0 #gt; 25 Joe 2004-02-25 0 #gt; 26 Joe 2004-02-26 0 #gt; 27 Joe 2004-02-27 0 #gt; 28 Joe 2004-02-28 0 #gt; 29 Joe 2004-02-29 0 #gt; 30 Joe 2004-03-01 0 #gt; 31 Joe 2004-03-02 0 #gt; 32 Joe 2004-03-03 0 #gt; 33 Joe 2004-03-04 0 #gt; 34 Joe 2004-03-05 4 #gt; 35 Joe 2004-03-06 0 #gt; 36 Joe 2004-03-07 0 #gt; 37 Joe 2004-03-08 0 #gt; 38 Joe 2004-03-09 0 #gt; 39 Joe 2004-03-10 0 #gt; 40 Joe 2004-03-11 0 #gt; 41 Joe 2004-03-12 0 #gt; 42 Joe 2004-03-13 0 #gt; 43 Joe 2004-03-14 0 #gt; 44 Joe 2004-03-15 0 #gt; 45 Joe 2004-03-16 0 #gt; 46 Joe 2004-03-17 0 #gt; 47 Joe 2004-03-18 0 #gt; 48 Joe 2004-03-19 0 #gt; 49 Joe 2004-03-20 0 #gt; 50 Joe 2004-03-21 0 #gt; 51 Joe 2004-03-22 0 #gt; 52 Joe 2004-03-23 0 #gt; 53 Joe 2004-03-24 0 #gt; 54 Joe 2004-03-25 0 #gt; 55 Joe 2004-03-26 0 #gt; 56 Joe 2004-03-27 0 #gt; 57 Joe 2004-03-28 0 #gt; 58 Joe 2004-03-29 0 #gt; 59 Joe 2004-03-30 0 #gt; 60 Joe 2004-03-31 0 #gt; 61 Joe 2004-04-01 0 #gt; 62 Joe 2004-04-02 0 #gt; 63 Joe 2004-04-03 0 #gt; 64 Joe 2004-04-04 0 #gt; 65 Joe 2004-04-05 0 #gt; 66 Joe 2004-04-06 0 #gt; 67 Joe 2004-04-07 0 #gt; 68 Joe 2004-04-08 0 #gt; 69 Joe 2004-04-09 0 #gt; 70 Joe 2004-04-10 0 #gt; 71 Joe 2004-04-11 0 #gt; 72 Joe 2004-04-12 0 #gt; 73 Joe 2004-04-13 0 #gt; 74 Joe 2004-04-14 0 #gt; 75 Joe 2004-04-15 0 #gt; 76 Joe 2004-04-16 0 #gt; 77 Joe 2004-04-17 0 #gt; 78 Joe 2004-04-18 0 #gt; 79 Joe 2004-04-19 0 #gt; 80 Joe 2004-04-20 0 #gt; 81 Joe 2004-04-21 0 #gt; 82 Joe 2004-04-22 0 #gt; 83 Joe 2004-04-23 0 #gt; 84 Joe 2004-04-24 0 #gt; 85 Joe 2004-04-25 0 #gt; 86 Joe 2004-04-26 0 #gt; 87 Joe 2004-04-27 0 #gt; 88 Joe 2004-04-28 0 #gt; 89 Joe 2004-04-29 0 #gt; 90 Joe 2004-04-30 0 #gt; 91 Joe 2004-05-01 0 #gt; 92 Joe 2004-05-02 0 #gt; 93 Joe 2004-05-03 0 #gt; 94 Joe 2004-05-04 0 #gt; 95 Joe 2004-05-05 0 #gt; 96 Joe 2004-05-06 0 #gt; 97 Joe 2004-05-07 0 #gt; 98 Joe 2004-05-08 0 #gt; 99 Joe 2004-05-09 0 #gt; 100 Joe 2004-05-10 0 #gt; 101 Joe 2004-05-11 0 #gt; 102 Joe 2004-05-12 0 #gt; 103 Joe 2004-05-13 0 #gt; 104 Joe 2004-05-14 0 #gt; 105 Joe 2004-05-15 0 #gt; 106 Joe 2004-05-16 0 #gt; 107 Joe 2004-05-17 0 #gt; 108 Joe 2004-05-18 0 #gt; 109 Joe 2004-05-19 0 #gt; 110 Joe 2004-05-20 0 #gt; 111 Joe 2004-05-21 0 #gt; 112 Joe 2004-05-22 0 #gt; 113 Joe 2004-05-23 0 #gt; 114 Joe 2004-05-24 0 #gt; 115 Joe 2004-05-25 0 #gt; 116 Joe 2004-05-26 0 #gt; 117 Joe 2004-05-27 0 #gt; 118 Joe 2004-05-28 0 #gt; 119 Joe 2004-05-29 0 #gt; 120 Joe 2004-05-30 0 #gt; 121 Joe 2004-05-31 0 #gt; 122 Joe 2004-06-01 0 #gt; 123 Joe 2004-06-02 0 #gt; 124 Joe 2004-06-03 0 #gt; 125 Joe 2004-06-04 0 #gt; 126 Joe 2004-06-05 0 #gt; 127 Joe 2004-06-06 0 #gt; 128 Joe 2004-06-07 0 #gt; 129 Joe 2004-06-08 0 #gt; 130 Joe 2004-06-09 0 #gt; 131 Joe 2004-06-10 0 #gt; 132 Joe 2004-06-11 0 #gt; 133 Joe 2004-06-12 0 #gt; 134 Joe 2004-06-13 0 #gt; 135 Joe 2004-06-14 0 #gt; 136 Joe 2004-06-15 0 #gt; 137 Joe 2004-06-16 0 #gt; 138 Joe 2004-06-17 0 #gt; 139 Joe 2004-06-18 0 #gt; 140 Joe 2004-06-19 0 #gt; 141 Joe 2004-06-20 0 #gt; 142 Joe 2004-06-21 0 #gt; 143 Joe 2004-06-22 0 #gt; 144 Joe 2004-06-23 0 #gt; 145 Joe 2004-06-24 0 #gt; 146 Joe 2004-06-25 0 #gt; 147 Joe 2004-06-26 0 #gt; 148 Joe 2004-06-27 0 #gt; 149 Joe 2004-06-28 0 #gt; 150 Joe 2004-06-29 0 #gt; 151 Joe 2004-06-30 0 #gt; 152 Joe 2004-07-01 0 #gt; 153 Joe 2004-07-02 0 #gt; 154 Joe 2004-07-03 0 #gt; 155 Joe 2004-07-04 0 #gt; 156 Joe 2004-07-05 0 #gt; 157 Joe 2004-07-06 0 #gt; 158 Joe 2004-07-07 0 #gt; 159 Joe 2004-07-08 0 #gt; 160 Joe 2004-07-09 0 #gt; 161 Joe 2004-07-10 0 #gt; 162 Joe 2004-07-11 0 #gt; 163 Joe 2004-07-12 0 #gt; 164 Joe 2004-07-13 0 #gt; 165 Joe 2004-07-14 0 #gt; 166 Joe 2004-07-15 0 #gt; 167 Joe 2004-07-16 0 #gt; 168 Joe 2004-07-17 0 #gt; 169 Joe 2004-07-18 0 #gt; 170 Joe 2004-07-19 0 #gt; 171 Joe 2004-07-20 0 #gt; 172 Joe 2004-07-21 0 #gt; 173 Joe 2004-07-22 0 #gt; 174 Joe 2004-07-23 0 #gt; 175 Joe 2004-07-24 0 #gt; 176 Joe 2004-07-25 0 #gt; 177 Joe 2004-07-26 0 #gt; 178 Joe 2004-07-27 0 #gt; 179 Joe 2004-07-28 0 #gt; 180 Joe 2004-07-29 0 #gt; 181 Joe 2004-07-30 0 #gt; 182 Joe 2004-07-31 0 #gt; 183 Joe 2004-08-01 0 #gt; 184 Joe 2004-08-02 0 #gt; 185 Joe 2004-08-03 0 #gt; 186 Joe 2004-08-04 0 #gt; 187 Joe 2004-08-05 0 #gt; 188 Joe 2004-08-06 0 #gt; 189 Joe 2004-08-07 0 #gt; 190 Joe 2004-08-08 0 #gt; 191 Joe 2004-08-09 10 #gt; 192 Joe 2004-08-10 0 #gt; 193 Joe 2004-08-11 0 #gt; 194 Joe 2004-08-12 0 #gt; 195 Joe 2004-08-13 9 #gt; 196 Joe 2004-08-14 0 #gt; 197 Joe 2004-08-15 0 #gt; 198 Joe 2004-08-16 0 #gt; 199 Joe 2004-08-17 0 #gt; 200 Joe 2004-08-18 0 #gt; 201 Joe 2004-08-19 0 #gt; 202 Joe 2004-08-20 0 #gt; 203 Joe 2004-08-21 0 #gt; 204 Joe 2004-08-22 0 #gt; 205 Joe 2004-08-23 0 #gt; 206 Joe 2004-08-24 0 #gt; 207 Joe 2004-08-25 0 #gt; 208 Joe 2004-08-26 0 #gt; 209 Joe 2004-08-27 0 #gt; 210 Joe 2004-08-28 0 #gt; 211 Joe 2004-08-29 0 #gt; 212 Joe 2004-08-30 0 #gt; 213 Joe 2004-08-31 0 #gt; 214 Joe 2004-09-01 0 #gt; 215 Joe 2004-09-02 0 #gt; 216 Joe 2004-09-03 0 #gt; 217 Joe 2004-09-04 0 #gt; 218 Joe 2004-09-05 0 #gt; 219 Joe 2004-09-06 0 #gt; 220 Joe 2004-09-07 0 #gt; 221 Joe 2004-09-08 0 #gt; 222 Joe 2004-09-09 0 #gt; 223 Joe 2004-09-10 0 #gt; 224 Joe 2004-09-11 0 #gt; 225 Joe 2004-09-12 0 #gt; 226 Joe 2004-09-13 0 #gt; 227 Joe 2004-09-14 0 #gt; 228 Joe 2004-09-15 0 #gt; 229 Joe 2004-09-16 0 #gt; 230 Joe 2004-09-17 0 #gt; 231 Joe 2004-09-18 0 #gt; 232 Joe 2004-09-19 0 #gt; 233 Joe 2004-09-20 0 #gt; 234 Joe 2004-09-21 0 #gt; 235 Joe 2004-09-22 0 #gt; 236 Joe 2004-09-23 0 #gt; 237 Joe 2004-09-24 0 #gt; 238 Joe 2004-09-25 0 #gt; 239 Joe 2004-09-26 0 #gt; 240 Joe 2004-09-27 0 #gt; 241 Joe 2004-09-28 0 #gt; 242 Joe 2004-09-29 0 #gt; 243 Joe 2004-09-30 0 #gt; 244 Joe 2004-10-01 0 #gt; 245 Joe 2004-10-02 0 #gt; 246 Joe 2004-10-03 0 #gt; 247 Joe 2004-10-04 0 #gt; 248 Joe 2004-10-05 0 #gt; 249 Joe 2004-10-06 0 #gt; 250 Joe 2004-10-07 0 #gt; 251 Joe 2004-10-08 0 #gt; 252 Joe 2004-10-09 0 #gt; 253 Joe 2004-10-10 0 #gt; 254 Joe 2004-10-11 0 #gt; 255 Joe 2004-10-12 0 #gt; 256 Joe 2004-10-13 0 #gt; 257 Joe 2004-10-14 0 #gt; 258 Joe 2004-10-15 0 #gt; 259 Joe 2004-10-16 0 #gt; 260 Joe 2004-10-17 0 #gt; 261 Joe 2004-10-18 0 #gt; 262 Joe 2004-10-19 0 #gt; 263 Joe 2004-10-20 15 #gt; 264 Joe 2004-10-21 0 #gt; 265 Joe 2004-10-22 0 #gt; 266 Joe 2004-10-23 0 #gt; 267 Joe 2004-10-24 0 #gt; 268 Joe 2004-10-25 0 #gt; 269 Joe 2004-10-26 0 #gt; 270 Joe 2004-10-27 0 #gt; 271 Joe 2004-10-28 0 #gt; 272 Joe 2004-10-29 0 #gt; 273 Joe 2004-10-30 0 #gt; 274 Joe 2004-10-31 0 #gt; 275 Joe 2004-11-01 0 #gt; 276 Joe 2004-11-02 1 #gt; 277 Joe 2004-11-03 0 #gt; 278 Joe 2004-11-04 0 #gt; 279 Joe 2004-11-05 0 #gt; 280 Joe 2004-11-06 0 #gt; 281 Joe 2004-11-07 0 #gt; 282 Joe 2004-11-08 0 #gt; 283 Joe 2004-11-09 0
Второй подход в целом приведет к появлению гораздо большего количества строк данных. Если вы хотите сохранить максимум 7 строк после любой даты с ненулевым hits
значением , вы можете сделать следующее:
df.filled2 = df.filled2 %gt;% group_by(name) %gt;% mutate(test=cumsum(hits gt; 0)) %gt;% group_by(name, test) %gt;% slice(1:8) %gt;% ungroup %gt;% select(-test)
Комментарии:
1. Это замечательно, спасибо вам!