分组差异

时间:2018-08-15 08:58:16

标签: r dplyr difference

很可能是重复的,但是我没有找到答案:

我想使用dplyrs summarise_all按组建立第一行和最后一行之间的差异。通过添加具有差异的新行或创建新的数据框。

假设我有这个df:

df <- data.frame(unit=rep(1:250, 4),  
             year=rep(c(2012, 2013, 2014, 2015), each=250),
             replicate(10,sample(0:50000,1000,rep=TRUE)))

我想了解基于该单位的每一列的2012年和2015年值之间的差异。

这不起作用:

df <- df %>% 
      group_by(unit) %>% 
      summarise_all(funs(diff))

3 个答案:

答案 0 :(得分:3)

您必须过滤数据以使其每单位仅包含两个值,即2012和2015:

df %>% 
  filter(year %in% c(2012, 2015)) %>% 
  group_by(unit) %>% 
  summarise_all(funs(diff))

# # A tibble: 250 x 12
# unit  year     X1     X2     X3     X4     X5     X6     X7     X8     X9    X10
# <int> <dbl>  <int>  <int>  <int>  <int>  <int>  <int>  <int>  <int>  <int>  <int>
#   1     1    3.   4509 -12192   6935  -5226   3538  14019 -10962  -3310  34014 -14668
# 2     2    3.  22811  -8568 -34469 -11743 -11569   7713  -5074  26502   6498  23340
# 3     3    3.  16886   8533 -16659   1585  17773 -30438   4723  -8048 -12521 -20980
# 4     4    3.  16888  -1732 -17721  26901 -24762  -9469  12574 -10933  17781  26397
# 5     5    3. -12643   -465  18461 -11637  40236  33825 -14037  18219  26781   7247
# 6     6    3. -27066 -14527 -18784 -13287  31836 -14046  46221   8493  20288 -17644
# 7     7    3.  -2777 -16123 -23697  -9932  18175 -20991 -38581   8505 -14498 -18397
# 8     8    3.  36854  -1865  -7608 -11197 -25044    344  24447   8201 -14640 -12060
# 9     9    3.  -6240  10678   2463  -3134   4442  10373   5075  -6204    218  20438
# 10    10    3.  -3496  -3284   2864  25562  -3473   4240 -17616  18310 -21326  10261
# # ... with 240 more rows

您必须执行此操作的原因是,否则diff将计算年份之间的所有差额,并且等于每单位大于1个结果,因此summarise_all无法处理。 / p>

答案 1 :(得分:1)

问题在于diff并没有达到您的期望。它可以有效地计算x[-n] - x[-1]

如果缺少2012或2015,则可以通过建立索引来实现更通用的解决方案:

df %>% 
  group_by(unit) %>% 
  arrange(unit, year) %>%
  summarise_at(vars(starts_with('X')), funs(.[1] - .[n()]))

或者创建更多漂亮的功能:

diff_ends <- function(x, order_var) {
  x[which.min(order_var)] - x[which.max(order_var)]
}
df %>% group_by(unit) %>%
  summarise_at(vars(starts_with('X')), funs(diff_ends(., year)))

答案 2 :(得分:1)

df %>% 
  group_by(unit) %>% 
  slice(c(1, n()) ) %>% 
    summarise_at(vars(X1:X10), diff)