按组 dplyr 为数据框中的最后 n 行创建新列

Create new columns for last n rows in dataframe by group dplyr

我有以下数据框:

df <- data.frame(
  ID  =  c(11041,11041,11041,11041,11041,11041,11042,11042,11042,11063,11063),
  p = c(2.9,3.6,4.8,2.6,2.2,3.9,6.5,2.9,1.4,0.7,5.1)
    )

这给出了这个输出:

      ID   p
1  11041 2.9
2  11041 3.6
3  11041 4.8
4  11041 2.6
5  11041 2.2
6  11041 3.9
7  11042 6.5
8  11042 2.9
9  11042 1.4
10 11063 0.7
11 11063 5.1

我正在尝试为 ID 的最后 n 个值(假设为 3)创建新列,因此我的新数据框如下所示:

      ID   p p1.1 p1.2 p1.3
1  11041 2.9   NA   NA  2.9
2  11041 3.6   NA  2.9  3.6
3  11041 4.8  2.9  3.6  4.8
4  11041 2.6  3.6  4.8  2.6
5  11041 2.2  4.8  2.6  2.2
6  11041 3.9  2.6  2.2  3.9
7  11042 6.5   NA   NA  6.5
8  11042 2.9   NA  6.5  2.9
9  11042 1.4  6.5  2.9  1.4
10 11063 0.7   NA   NA  0.7
11 11063 5.1   NA  0.7  5.1

理想情况下,我希望能够指定最后 n 个值,这样如果我想要最后 5 个值(创建 p.1、p.2、p.3、p.4、p.5)我可以做这个。但是n可以是任意数字,比如3,5,10,15等

对于 dplyr,我已经尝试了 spreadpivot_wider 但无法使它们工作。

您可以这样使用 data.table shift

library(data.table)
setDT(df)[, c(paste0("p1.",1:3)):=shift(p, 2:0), by=ID][]

输出:

       ID   p p1.1 p1.2 p1.3
 1: 11041 2.9   NA   NA  2.9
 2: 11041 3.6   NA  2.9  3.6
 3: 11041 4.8  2.9  3.6  4.8
 4: 11041 2.6  3.6  4.8  2.6
 5: 11041 2.2  4.8  2.6  2.2
 6: 11041 3.9  2.6  2.2  3.9
 7: 11042 6.5   NA   NA  6.5
 8: 11042 2.9   NA  6.5  2.9
 9: 11042 1.4  6.5  2.9  1.4
10: 11063 0.7   NA   NA  0.7
11: 11063 5.1   NA  0.7  5.1

一种概括方法如下:

  1. 制作辅助函数
f <- function(v,n) {
  setNames(shift(v,(n-1):0), paste0(deparse(substitute(v)),".",1:n))
}
  1. 通过ID申请功能;这里我使用 n=5
df[, f(p,5), by=ID]

输出:

       ID p.1 p.2 p.3 p.4 p.5
 1: 11041  NA  NA  NA  NA 2.9
 2: 11041  NA  NA  NA 2.9 3.6
 3: 11041  NA  NA 2.9 3.6 4.8
 4: 11041  NA 2.9 3.6 4.8 2.6
 5: 11041 2.9 3.6 4.8 2.6 2.2
 6: 11041 3.6 4.8 2.6 2.2 3.9
 7: 11042  NA  NA  NA  NA 6.5
 8: 11042  NA  NA  NA 6.5 2.9
 9: 11042  NA  NA 6.5 2.9 1.4
10: 11063  NA  NA  NA  NA 0.7
11: 11063  NA  NA  NA 0.7 5.1