按组 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
,我已经尝试了 spread
和 pivot_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
一种概括方法如下:
- 制作辅助函数
f <- function(v,n) {
setNames(shift(v,(n-1):0), paste0(deparse(substitute(v)),".",1:n))
}
- 通过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
我有以下数据框:
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
,我已经尝试了 spread
和 pivot_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
一种概括方法如下:
- 制作辅助函数
f <- function(v,n) {
setNames(shift(v,(n-1):0), paste0(deparse(substitute(v)),".",1:n))
}
- 通过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