adicionar valores padrão aos pares item x grupo que não têm um valor (df%>% spread%>% reunir parece estranho)

Versão curta

Como fazer a operação

df1 %>% spread(groupid, value, fill = 0) %>% gather(groupid, value, one, two)

de uma maneira mais natural?

Versão longa

Dado 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.

questionAnswers(2)

yourAnswerToTheQuestion