adicionar valores padrão aos pares item x grupo que não têm um valor (df%>% spread%>% reunir parece estranho)
Como fazer a operação
df1 %>% spread(groupid, value, fill = 0) %>% gather(groupid, value, one, two)
de uma maneira mais natural?
Versão longaDado um quadro de dados
df1 <- data.frame(groupid = c("one","one","one","two","two","two", "one"),
value = c(3,2,1,2,3,1,22),
itemid = c(1:6, 6))
para muitos pares itemid e groupid, temos um valor, para alguns itens id existem grupos group onde não há valor. Eu quero adicionar um valor padrão para esses casos. Por exemplo. para o itemid 1 e groupid "two" não há valor, quero adicionar uma linha em que isso obtenha um valor padrão.
O código tidyr a seguir consegue isso, mas parece uma maneira estranha de fazer isso (o valor padrão adicionado aqui é 0).
df1 %>% spread(groupid, value, fill = 0) %>% gather(groupid, value, one, two)
Estou procurando sugestões sobre como fazer isso de uma maneira mais natural.
Como em algumas semanas, olhando para o código acima, eu provavelmente ficaria confuso sobre seu efeito, escrevi uma função envolvendo-o:
#' Add default values for missing groups
#'
#' Given data about items where each item is identified by an id, and every
#' item can have a value in every group; add a default value for all groups
#' where an item doesn't have a value yet.
add_default_value <- function(data, id, group, value, default) {
id = as.character(substitute(id))
group = as.character(substitute(group))
value = as.character(substitute(value))
groups <- unique(as.character(data[[group]]))
# spread checks that the columns outside of group and value uniquely
# determine the row. Here we check that that already is the case within
# each group using only id. I.e. there is no repeated (id, group).
id_group_cts <- data %>% group_by_(id, group) %>% do(data.frame(.ct = nrow(.)))
if (any(id_group_cts$.ct > 1)) {
badline <- id_group_cts %>% filter(.ct > 1) %>% top_n(1, .ct)
stop("There is at least one (", id, ", ", group, ")",
" combination with two members: (",
as.character(badline[[id]]), ", ", as.character(badline[[group]]), ")")
}
gather_(spread_(data, group, value, fill = default), group, value, groups)
}
Última observação: o motivo de querer isso é: meus grupos são ordenados (semana1, semana2, ...) e estou procurando que todos os IDs tenham um valor em cada grupo, para que, depois de classificar os grupos por ID, eu possa usar o cumsum para obter um total semanal em execução que também é mostrado nas semanas em que o total atual não aumentou.