У меня есть data.frame
групп и дат. Как заполнить все отсутствующие даты в диапазоне дат max-max для каждой группы?Как заполнить отсутствующие даты в диапазоне по группе
В идеале я бы сделал это в dplyr
. Но в конечном счете, я бы просто хотел сделать это эффективно, используя как можно меньше строк (читаемого) кода. Ниже приведен минимальный пример. На самом деле у меня много дат и групп. Оба моих подхода выглядят уродливо. Должен быть лучший способ, не так ли?
#### setup ####
library(sqldf)
library(dplyr)
df <- data.frame(the_group = rep(LETTERS[1:2], each=3), date = Sys.Date() + c(0:2, 1:3), stringsAsFactors = F) %>%
tbl_df() %>%
slice(-2) # represents that I may be missing data in a range!
#### dplyr approach with cross join dummy ####
full_seq <- data.frame(cross_join_dummy = 1, date = seq.Date(from=min(df$date), to=max(df$date), by = "day"))
range_by_group <- df %>%
group_by(the_group) %>%
summarise(min_date = min(date), max_date = max(date)) %>%
ungroup() %>%
mutate(cross_join_dummy = 1)
desired <- range_by_group %>%
inner_join(full_seq, by="cross_join_dummy") %>%
filter(date >= min_date, date <= max_date) %>%
select(the_group, date)
#### sqldf approach ####
full_seq <- data.frame(date = as.character(seq.Date(from=min(df$date), to=max(df$date), by="day")))
df <- df %>%
mutate(date = as.character(date))
range_by_group <- sqldf("
SELECT the_group, MIN(date) AS min_date, MAX(date) AS max_date
FROM df
GROUP BY the_group
")
desired <- sqldf("
SELECT rbg.the_group, fs.date
FROM range_by_group rbg
JOIN full_seq fs
ON fs.date BETWEEN rbg.min_date AND rbg.max_date
")
По-прежнему возникают проблемы с пониманием того, почему работает подход «без пакетов».Особенно с 'the_group [1]' и 'with' – lowndrul
Это то же самое, что' do.call ("rbind", by (df, df $ the_group, function (x) data.frame (the_group = x $ the_group [ 1], date = seq (min (x $ date), max (x $ date), by = "day")))) 'кроме того, что мы использовали' with', чтобы сократить его. 'the_group' является константой внутри группы, поэтому мы просто использовали первый компонент, так как вы не можете смешивать два разных вектора длины в кадре данных, если один из них не имеет длины 1. –
Немного расширенный ответ в свете улучшений сегодня (OCT 2017) будет использовать функцию «nest()» вместо split, а также комбинацию карт, которую OP использует здесь для своего примера «tidyverse». Немного чистая презентация. В противном случае логика здесь останется прежней. – jacobsg