Сворачивание строк с помощью dplyr

Я новичок в R и пытаюсь свернуть строки на основе значений строк с помощью dplyr. В следующем примере показаны образцы данных.

set.seed(123)

df<-data.frame(A=c(rep(1:4,4)),
               B=runif(16,min=0,max=1),
               C=rnorm(16, mean=1,sd=0.5))

   A B          c
1  1 0.36647435 0.7485365
2  2 0.51864614 0.8654337
3  3 0.04596929 0.9858012
4  4 0.15479619 1.1294208
5  1 0.76712372 1.2460700
6  2 0.17666676 0.7402996
7  3 0.89759874 1.2699954
8  4 0.90267735 0.7101804
9  1 0.91744223 0.3451281
10 2 0.25472599 0.8604743
11 3 0.10933985 0.8696796
12 4 0.71656017 1.2648846
13 1 0.21157810 1.3170205
14 2 0.14947268 1.2789700
15 3 0.92251060 1.5696901
16 4 0.30090579 1.7642853

Я хочу суммировать / свернуть две строки при условии, что строки в столбце A со значениями 1 и 2 как одна строка (как среднее значение строк 1 и 2). Следовательно, окончательный результат будет иметь только 12 строк, потому что остальные 4 строки были свернуты.

Я попытался использовать следующую dplyr функцию, но безуспешно.

install.packages ("tidyverse") библиотека (tidyverse)

df %>% summarize_each( fun(i){ for i %in% c(1,2)funs(mean) })

Ожидаемый результат выглядит примерно так:

   A    B           C
1  1.5  0.4425602   0.8069851
3  3    0.04596929  0.9858012
4  4    0.15479619  1.1294208
5  1.5  0.4718952   0.9931848
7  3    0.89759874  1.2699954
8  4    0.90267735  0.7101804
9  1.5  0.5860841   0.6028012
11 3    0.10933985  0.8696796
12 4    0.71656017  1.2648846
13 1.5  0.1805254   1.297995
15 3    0.92251060  1.5696901
16 4    0.30090579  1.7642853

Заранее спасибо.


person G1124E    schedule 28.10.2017    source источник
comment
строки не полностью свернуты, они свернуты 2 на 2, и вы не объясняете правило, в ваших реальных данных действительно есть последовательности из 4 строк за другой, как это?   -  person Moody_Mudskipper    schedule 29.10.2017
comment
@Moody_Mudskipper: строки должны быть свернуты, если значения в столбце A равны 1 и 2.   -  person G1124E    schedule 29.10.2017
comment
При генерации случайных данных было бы полезно включить в ваш пример вызов set.seed(). Таким образом, другие могут точно воспроизвести ваши результаты!   -  person Mikko Marttila    schedule 29.10.2017
comment
Я читал это, но, похоже, он работает группами по 4 человека, что является предположением, что выбранный ответ был принят, но не явным в вашем вопросе.   -  person Moody_Mudskipper    schedule 29.10.2017


Ответы (2)


Один из вариантов - обработать строки с A, равным 1 или 2, отдельно от других строк, а затем связать их вместе:

set.seed(3)
df<-data.frame(A=c(rep(1:4,4)),B=runif(16,min=0,max=1),c=rnorm(16, mean=1,sd=0.5))

df %>% 
  filter(A %in% 1:2) %>% 
  group_by(tmp=cumsum(A==1)) %>% 
  summarise_all(mean) %>% 
  ungroup %>% select(-tmp) %>% 
  bind_rows(df %>% filter(!A %in% 1:2))
       A         B         c
   <dbl>     <dbl>     <dbl>
 1   1.5 0.4877790 1.0121278
 2   1.5 0.6032474 0.8840735
 3   1.5 0.6042946 0.5996850
 4   1.5 0.5456424 0.6198039
 5   3.0 0.3849424 0.6276092
 6   4.0 0.3277343 0.4343907
 7   3.0 0.1246334 1.0760229
 8   4.0 0.2946009 0.8461718
 9   3.0 0.5120159 1.6121568
10   4.0 0.5050239 1.0999058
11   3.0 0.8679195 0.8981359
12   4.0 0.8297087 0.1667626
person eipi10    schedule 28.10.2017
comment
Спасибо @ eipi10. Мне было интересно, как можно сохранить порядок строк, чтобы их можно было расположить в порядке возрастания, например: 1,5, 3, 4, 1,5 3, 4, 1,5 3, 4, 1,5 3, 4. - person G1124E; 29.10.2017

person    schedule
comment
Я попытался запустить код, но получил это сообщение об ошибке: Error in mutate_impl(.data, dots) : wrong result size (64), expected 16 or 1 Я не уверен, зачем нам нужен аргумент each=4 в первой group_by функции. Я также попытался запустить код, опуская аргумент each=4, но вывод не был упорядочен. как и ожидалось. Не могли бы вы пролить на это немного света? - person G1124E; 30.10.2017
comment
Ах, это опечатка: должно быть, оставил это, пока делал какой-то стиль. Вы можете опустить первый 4, но вам понадобится each, чтобы сгруппировать 4 соседних строки. Я отредактировал соответственно. - person Mikko Marttila; 30.10.2017