Подтвердить что ты не робот

Dplyr summaryize() и summise_each() делают дополнительные вызовы предоставленным функциям

Кажется, что summarise и summarise_each делают ненужные дополнительные вызовы для функций обратного вызова, которые они предоставляют. Предположим, что мы имеем следующее

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

который выглядит следующим образом:

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

Далее предположим, что у нас есть (потенциально дорогостоящая) функция

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

которые мы хотели бы применить к каждой из наших переменных в каждой группе. Используя dplyr, мы можем сделать это следующим образом:

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

Однако вывод показывает, что f было вызвано еще одним временем для каждой переменной в 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

Такая же проблема возникает при использовании 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

Почему это происходит, и как избежать предотвращения summarise и summarise_each от дополнительных вызовов?

(используется R версия 3.3.0 и dplyr версия 0.5.0)

EDIT: Похоже, что проблема связана с взаимодействием между group_by и summarise/summarise_each. Без группировки никаких дополнительных вызовов не производится. Кроме того, mutate и mutate_each не страдают от этой проблемы. (Кредит: eddi и eipi10 для этих выводов)

4b9b3361

Ответ 1

Хотя эта проблема все еще присутствует в dplyr 0.5.0 (опубликовано в 2016-06-24), она исправлена ​​в репродуцировании dplyr GitHub. Это было исправлено с помощью этого коммита, сделанного в 2016-09-24. Я подтвердил, что могу воспроизвести проблему, когда я проверяю и создаю версию при предыдущем фиксации, но не при создании из этого или последующих.

(И да, я попробовал целую кучу других, прежде чем нашел это. Почему я так долго нахожусь в надежде заработать воображаемые интернет-точки, я оставляю вопрос для своего терапевта.:)

В частности, в функции SEXP process_data(const Data& gdf) в inst/include/dplyr/Result/CallbackProcessor.h обратите внимание на эти изменения:

  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

и

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

[Комментарии, добавленные мной, а не часть фактического источника]