dplyr summarise () et summarise each() font des appels supplémentaires aux fonctions fournies

Il semble que summarise et summarise_each font des appels supplémentaires inutiles aux fonctions de rappel qui leur sont fournies. Supposons que nous ayons ce qui suit

X <- data.frame( Group = rep(c("G1","G2"),2:3), Var1 = 1:5, Var2 = 11:15 )

, Qui ressemble à ceci:

   Group Var1 Var2
 1    G1    1   11
 2    G1    2   12
 3    G2    3   13
 4    G2    4   14
 5    G2    5   15

Supposons En outre que nous ayons une fonction (potentiellement coûteuse)

f <- function(v)
{
   cat( "Calling f with vector", v, "n" )
   ## ...additional bookkeeping and processing...
   mean(v)
}

Que nous aimerions appliquer à chacune de nos variables dans chaque groupe. En utilisant dplyr, nous pourrions procéder de la manière suivante:

X %>% group_by( Group ) %>% summarise_each( funs(f) )

Cependant, la sortie montre que f a été appelé une fois supplémentaire pour chaque variable dans G1:

Calling f with vector 1 2 
Calling f with vector 1 2 
Calling f with vector 3 4 5 
Calling f with vector 11 12 
Calling f with vector 11 12 
Calling f with vector 13 14 15 
# A tibble: 2 x 3
   Group  Var1  Var2
  <fctr> <dbl> <dbl> 
1     G1   1.5  11.5
2     G2   4.0  14.0

, Le même problème est présent lors de l'utilisation de summarize:

> X %>% group_by( Group ) %>% summarise( test = f(Var1) )
Calling f with vector 1 2
Calling f with vector 1 2
Calling f with vector 3 4 5
# A tibble: 2 × 2
   Group  test
  <fctr> <dbl>
1     G1   1.5
2     G2   4.0

Pourquoi cela se produit-il et comment empêcherait-on summarise et summarise_each de faire ces appels supplémentaires?

(ceci utilise R Version 3.3.0 et dplyr version 0.5.0)

EDIT:, Il semble que la question a à voir avec l'interaction entre group_by et summarise/summarise_each. Sans le regroupement, aucun appel supplémentaire n'est effectué. En outre, mutate et mutate_each ne souffrent pas de ce problème. (Crédit: eddi et eipi10 pour ces résultats)

21
demandé sur Community 2016-08-30 23:43:05

1 réponses

Bien que ce problème soit toujours présent dans dplyr 0.5.0 (publié 2016-06-24), il est corrigé dans la repro GitHub de dplyr. Il a été corrigé avec ce commit fait le 2016-09-24. J'ai confirmé que je peux reproduire le problème lorsque je vérifie et construis la version lors de la validation précédente, mais pas lors de la construction à partir de celle-ci ou des suivantes.

(et oui, j'ai essayé tout un tas d'autres avant de le trouver. Pourquoi je vais à de telles longueurs dans l'espoir de gagner des Points Internet imaginaires, Je laisser une question pour mon thérapeute. :)

En particulier, dans la fonction SEXP process_data(const Data& gdf) dans inst/include/dplyr/Result/CallbackProcessor.h, notez ces changements:

  CLASS* obj = static_cast<CLASS*>(this);
  typename Data::group_iterator git = gdf.group_begin();

  RObject first_result = obj->process_chunk(*git);
  ++git; // This line was added

Et

  for (int i = 1; i < ngroups; ++git, ++i) { // changed from starting at i = 0
    RObject chunk = obj->process_chunk(*git);

[commentaires ajoutés par moi, ne faisant pas partie de la source réelle]

5
répondu Tim Goodman 2017-02-27 04:58:15