如何使用 dplyr 对数据帧中的分组数据进行扩展和插值,每组的插值点数量相等?
How to expand and interpolate grouped data in dataframe with the equal number of interpolation points for each group using dplyr?
我想按组对数据框中的值进行插值,以便每个组都具有相同数量的数据点。
到目前为止,我围绕 expand() 和 na.approx() 函数尝试了几件事,但没有成功。
举个例子最容易理解:我想转换这个dataframe:
> df.test
ID x y
1 A 0 9.0
2 A 2 8.0
3 B 10 1.0
4 B 20 1.5
5 B 30 3.0
至此
> df.test.result
# A tibble: 10 x 3
ID x y
<fct> <dbl> <dbl>
1 A 0 9
2 A 0.5 8.75
3 A 1 8.5
4 A 1.5 8.25
5 A 2 8
6 B 10 1
7 B 15 1.25
8 B 20 1.5
9 B 25 2.25
10 B 30 3
我们的想法是为 A 组和 B 组各创建 5 个数据点,其中缺失的 y 值由线性插值确定。例如,对于组 "B",它应该在 x=15、x=25(10、20、30 已经存在)处进行插值以获得 5 分。要获得 x=15,它应该对最近数据点的 y 值进行线性插值(在本例中为 x=10 和 x=20)。在这个例子中,x=15 位于两者的中间,这将给出 (x,y)=(15,1.25)。
首先,我扩展了组(以便在 y 列中接收 NA,稍后进行插值)
df.test.expand <- df.test %>%
group_by(ID) %>%
expand(x=full_seq(x,1)) %>%
ungroup() %>%
left_join(df.test)
但是 x 列总是递增 1,我没有为每个组获得相同的样本量(例如 5 个元素)。
有没有更直接的方法来做这个插值?
我想,这是一个常见的问题,应该在 dplyr 中直截了当。
感谢您的帮助!
一种可能是:
df %>%
group_by(ID) %>%
summarise_all(~ list(seq(first(.), last(.), len = 5))) %>%
unnest()
ID x y
<chr> <dbl> <dbl>
1 A 0 9
2 A 0.5 8.75
3 A 1 8.5
4 A 1.5 8.25
5 A 2 8
6 B 10 1
7 B 15 1.5
8 B 20 2
9 B 25 2.5
10 B 30 3
执行线性插值(也使用zoo
):
df %>%
group_by(ID) %>%
complete(x = seq(first(x), last(x), len = 5)) %>%
mutate(y = na.approx(y))
ID x y
<chr> <dbl> <dbl>
1 A 0 9
2 A 0.5 8.75
3 A 1 8.5
4 A 1.5 8.25
5 A 2 8
6 B 10 1
7 B 15 1.25
8 B 20 1.5
9 B 25 2.25
10 B 30 3
我想按组对数据框中的值进行插值,以便每个组都具有相同数量的数据点。
到目前为止,我围绕 expand() 和 na.approx() 函数尝试了几件事,但没有成功。
举个例子最容易理解:我想转换这个dataframe:
> df.test
ID x y
1 A 0 9.0
2 A 2 8.0
3 B 10 1.0
4 B 20 1.5
5 B 30 3.0
至此
> df.test.result
# A tibble: 10 x 3
ID x y
<fct> <dbl> <dbl>
1 A 0 9
2 A 0.5 8.75
3 A 1 8.5
4 A 1.5 8.25
5 A 2 8
6 B 10 1
7 B 15 1.25
8 B 20 1.5
9 B 25 2.25
10 B 30 3
我们的想法是为 A 组和 B 组各创建 5 个数据点,其中缺失的 y 值由线性插值确定。例如,对于组 "B",它应该在 x=15、x=25(10、20、30 已经存在)处进行插值以获得 5 分。要获得 x=15,它应该对最近数据点的 y 值进行线性插值(在本例中为 x=10 和 x=20)。在这个例子中,x=15 位于两者的中间,这将给出 (x,y)=(15,1.25)。
首先,我扩展了组(以便在 y 列中接收 NA,稍后进行插值)
df.test.expand <- df.test %>%
group_by(ID) %>%
expand(x=full_seq(x,1)) %>%
ungroup() %>%
left_join(df.test)
但是 x 列总是递增 1,我没有为每个组获得相同的样本量(例如 5 个元素)。
有没有更直接的方法来做这个插值?
我想,这是一个常见的问题,应该在 dplyr 中直截了当。
感谢您的帮助!
一种可能是:
df %>%
group_by(ID) %>%
summarise_all(~ list(seq(first(.), last(.), len = 5))) %>%
unnest()
ID x y
<chr> <dbl> <dbl>
1 A 0 9
2 A 0.5 8.75
3 A 1 8.5
4 A 1.5 8.25
5 A 2 8
6 B 10 1
7 B 15 1.5
8 B 20 2
9 B 25 2.5
10 B 30 3
执行线性插值(也使用zoo
):
df %>%
group_by(ID) %>%
complete(x = seq(first(x), last(x), len = 5)) %>%
mutate(y = na.approx(y))
ID x y
<chr> <dbl> <dbl>
1 A 0 9
2 A 0.5 8.75
3 A 1 8.5
4 A 1.5 8.25
5 A 2 8
6 B 10 1
7 B 15 1.25
8 B 20 1.5
9 B 25 2.25
10 B 30 3