在聚合中使用循环但从不同的组中抽取?

Use loop inside aggregate but draw from different groups?

我不知道如何想办法摆脱这个。这是我的数据:

group <- c(1, 1, 1, 2, 2, 2, 2, 2, 3, 1, 1, 1, 2, 2)
gdp <- c(3.5, 4.2, 5, 4, 4.2, 5, 5.5, 6, 3.5, 3.4, 4.0, 4.1, 4.3, 4.7)
year <- c(rep(1970, 9), rep(1971, 5))
df <- data.frame(group, gdp, year) 

  group gdp year
1   1   3.5 1970
2   1   4.2 1970
3   1   5.0 1970
4   2   4.0 1970
5   2   4.2 1970
6   2   5.0 1970
7   2   5.5 1970
8   2   6.0 1970
9   3   3.5 1970
10  1   3.4 1971
11  1   4.0 1971
12  1   4.1 1971
13  2   4.3 1971
14  2   4.7 1971

我想执行以下操作:对于每个 year,我想找出 group 中最后一个变量与下一个变量中第一个变量之间 gdp 的差异group。例如:gdp btwn 第 3 行和第 4 行,btwn 第 8 行和第 9 行等有什么区别。显然需要自动化,因为实际数据集很大。

我试图在聚合中使用一个函数——聚合将由 year 执行,而该函数将是一个 for loop 滚动遍历每个 group,但是然后我将我想做的事情翻译成代码的能力就崩溃了。如何识别一组中的最后一个变量并使用下一组中的第一个变量进行计算?我对索引编制不够熟练,无法对此进行排序。有什么建议?

dplyr解决方案类似于data.table评论栏中@akrun的解决方案

library(dplyr)
df %>% group_by(year, group) %>% 
    summarise(x1 = gdp[1], x2 = gdp[n()]) %>% 
    mutate(dff = x1 - lag(x2)) %>% 
    na.omit %>% select(-x1, -x2)
#  year group  dff
#1 1970     2 -1.0
#2 1970     3 -2.5
#3 1971     2  0.2

我们可以使用 data.table。将 'data.frame' 转换为 'data.table' (setDT(df))。获取每个分组变量 (.(group, year)) 的第一个元素 (gdp[1L]) 和最后一个元素 (gdp[.N])。在分别为每个 'year' 删除 'V1' 和 'V2' 的第一个和最后一个观察值后,减去新变量 ('V1') 和 ('V2')。

library(data.table)
setDT(df)[, list(gdp[1L], gdp[.N]) ,.(group, year)][,
                         V1[-1L]-V2[-.N], year]
#   year   V1
#1: 1970 -1.0
#2: 1970 -2.5
#3: 1971  0.2

如果我们需要 "group" 列

setDT(df)[, list(gdp[1L], gdp[.N]), , .(group, year)][,
 list(group=group,dff=V1-shift(V2)) , year][complete.cases(dff)]
 #   year group  dff
#1: 1970     2 -1.0
#2: 1970     3 -2.5
#3: 1971     2  0.2