как сделать перекрестные вычисления в dplyr? - PullRequest
0 голосов
/ 04 декабря 2018

есть фрейм данных, который содержит вложенную информацию.Скажем, количество учеников, количество учеников в классе А и количество учеников в классе В в каждой школе.Так что ученики = n.pupilsA + n.pupilsB + other_pupils

a <- data.frame(
  city = c(rep('New York',3), rep('Washington',3)),
  n = c(5, 2, 1, 5, 2, 1),
  name = c(
    'pupils',
    'classA',
    'classB',
    'pupils',
    'classA',
    'classB'
  )
)

output:

        city n   name
1   New York 5 pupils
2   New York 2 classA
3   New York 1 classB
4 Washington 5 pupils
5 Washington 2 classA
6 Washington 1 classB

Есть ли умный способ (предположительно, с использованием dplyr), чтобы сделать групповую операцию, котораядобавит в каждую группу «другое», что будет разницей между «учениками» и «учениками - класс А» + «учениками - класс В».Таким образом, результат будет примерно таким:

        city   type npupils
1   New York classA       2
2   New York classB       1
3   New York pupils       5
4   New York  other       2
5 Washington classA       2
6 Washington classB       1
7 Washington pupils       5
8 Washington  other       2

Единственный способ, который, как я думал, может сработать, - это распределить его, вычислить разницу между столбцами и собрать обратно, используя tidyr:

a %>%
  spread(name, n) %>%
  mutate(other = pupils - classA - classB) %>%
  gather(type, npupils, c('classA', 'classB', 'pupils', 'other')) %>%
  arrange(city)

который работает, но мне интересно, есть ли более хороший способ?

1 Ответ

0 голосов
/ 04 декабря 2018

Мы можем создать итоговый фрейм данных и привязать его к исходному.Для каждого city мы вычисляем n, вычитая значение n, где name == 'pupils', из оставшихся значений в группе и создаем столбец name как «Другое» и добавляем эти строки в исходный кадр данных, используя * 1006.*.

library(dplyr)

bind_rows(a, a %>%
              group_by(city)%>%
              summarise(n = n[name == 'pupils'] - sum(n[name != 'pupils']), 
                       name = "Other")) %>%
arrange(city)


#        city n   name
#1   New York 5 pupils
#2   New York 2 classA
#3   New York 1 classB
#4   New York 2  Other
#5 Washington 5 pupils
#6 Washington 2 classA
#7 Washington 1 classB
#8 Washington 2  Other

Примечание. Здесь я предполагаю, что у вас есть только одна запись "учеников" для каждого city, иначе мы можем использовать which.max для получения первой записи.

...