有一个包含嵌套信息的数据框。假设每所学校的学生人数,A级学生人数和B级学生人数。 这样学生= n。小学生A + n。小学生B + other_小学生
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'
)
)
输出:
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)进行分组操作,该操作将添加到每个组“其他”中,这将在“学生”和“学生-A类” +“学生-B类”之间有所区别。因此结果将是这样的:
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)
哪个可行,但我想知道是否还有更好的方法?
答案 0 :(得分:5)
我们可以创建一个汇总的数据框并将其绑定到原始数据框。对于每个city
,我们通过将组中的剩余值减去n
的值n
来计算name == 'pupils'
,并创建一个name
列作为“其他”,使用bind_rows
将这些行添加到原始数据框中。
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
来获得第一个条目。