使用不同 time-steps 的值加入 R tibbles
Join R tibbles with values taken with different time-steps
我正在尝试连接两个包含不同时间步长的值的小标题。
例如:
data_fine <- tibble(t_fine = seq(50,51, length.out = 25),value_fine = seq(1,25))
head(data_fine)
# A tibble: 6 x 2
t_fine value_fine
<dbl> <int>
1 50 1
2 50.0 2
3 50.1 3
4 50.1 4
5 50.2 5
6 50.2 6
data_coarse <- tibble(t_coarse = seq(50,51, length.out = 10),value_coarse = seq(1,10))
head(data_coarse)
# A tibble: 6 x 2
t_coarse value_coarse
<dbl> <int>
1 50 1
2 50.1 2
3 50.2 3
4 50.3 4
5 50.4 5
6 50.6 6
我想在 data_fine
中添加一列,其中 values_coarse
是在同一时期拍摄的(分配在最近的前一个或下一个 t_coarse
上拍摄的值)。例如,如果我将 data_fine
分配给具有前一个 t_coarse
的那些,我想得到类似 data_tot
:
的东西
head(data_tot)
# A tibble: 5 x 3
t_fine value_fine values_coarse
<dbl> <int> <dbl>
1 50 1 1
2 50.0 2 1
3 50.1 3 2
4 50.1 4 2
5 50.2 5 3
即使时间不像本例那样平均分配,我也希望它能正常工作。
有人知道怎么做吗?
一个可能出乎意料的棘手部分是您的 t_fine 值实际上是“50.00000”“50.04167”“50.08333”“50.12500”“50.16667”等,而您的 t_coarse 值是“ 50.00000" "50.11111" "50.22222" "50.33333" "50.44444" 等,因为您在一个范围内请求 25 或 10 个点,包括端点。因此,您将 24 位与 9 位进行比较,并且在大多数情况下不会完全对齐,即使第一个小数位匹配也是如此。
ggplot() +
geom_segment(data = data_fine, color = "gray70",
aes(x = t_fine, xend = t_fine, y = 0, yend = value_fine)) +
geom_segment(data = data_coarse,
aes(x = t_coarse, xend = t_coarse, y = 0, yend = value_coarse))
如果您的数据很小,将这些排列成最接近匹配的一种蛮力方法是计算所有成对时间距离,select 计算每个时间距离的最佳值。如果您的数据超过 10k 行,我预计这会开始变得太低效,并且在 data.table
.
中使用非 equi 连接会变得更快
library(tidyverse)
crossing(data_fine, data_coarse) %>% # from tidyr, incl in tidyverse
mutate(t_diff = abs(t_coarse - t_fine)) %>%
group_by(t_fine) %>%
slice_min(t_diff) %>%
ungroup()
## A tibble: 26 x 5
# t_fine value_fine t_coarse value_coarse t_diff
# <dbl> <int> <dbl> <int> <dbl>
# 1 50 1 50 1 0
# 2 50.0 2 50 1 0.0417
# 3 50.1 3 50.1 2 0.0278
# 4 50.1 4 50.1 2 0.0139
# 5 50.2 5 50.1 2 0.0556
# 6 50.2 6 50.2 3 0.0139
# 7 50.2 7 50.2 3 0.0278
# 8 50.3 8 50.3 4 0.0417
# 9 50.3 9 50.3 4 0
#10 50.4 10 50.3 4 0.0417
## … with 16 more rows
这里有一张图可以直观地检查结果:
ggplot() +
geom_segment(data = data_fine, color = "gray70",
aes(x = t_fine, xend = t_fine, y = 0, yend = value_fine)) +
geom_segment(data = data_tot, color = "red", # This is output of prior chunk
aes(x = t_fine, xend = t_coarse, y = 0, yend = value_coarse)) +
geom_segment(data = data_coarse,
aes(x = t_coarse, xend = t_coarse, y = 0, yend = value_coarse))
我正在尝试连接两个包含不同时间步长的值的小标题。 例如:
data_fine <- tibble(t_fine = seq(50,51, length.out = 25),value_fine = seq(1,25))
head(data_fine)
# A tibble: 6 x 2
t_fine value_fine
<dbl> <int>
1 50 1
2 50.0 2
3 50.1 3
4 50.1 4
5 50.2 5
6 50.2 6
data_coarse <- tibble(t_coarse = seq(50,51, length.out = 10),value_coarse = seq(1,10))
head(data_coarse)
# A tibble: 6 x 2
t_coarse value_coarse
<dbl> <int>
1 50 1
2 50.1 2
3 50.2 3
4 50.3 4
5 50.4 5
6 50.6 6
我想在 data_fine
中添加一列,其中 values_coarse
是在同一时期拍摄的(分配在最近的前一个或下一个 t_coarse
上拍摄的值)。例如,如果我将 data_fine
分配给具有前一个 t_coarse
的那些,我想得到类似 data_tot
:
head(data_tot)
# A tibble: 5 x 3
t_fine value_fine values_coarse
<dbl> <int> <dbl>
1 50 1 1
2 50.0 2 1
3 50.1 3 2
4 50.1 4 2
5 50.2 5 3
即使时间不像本例那样平均分配,我也希望它能正常工作。
有人知道怎么做吗?
一个可能出乎意料的棘手部分是您的 t_fine 值实际上是“50.00000”“50.04167”“50.08333”“50.12500”“50.16667”等,而您的 t_coarse 值是“ 50.00000" "50.11111" "50.22222" "50.33333" "50.44444" 等,因为您在一个范围内请求 25 或 10 个点,包括端点。因此,您将 24 位与 9 位进行比较,并且在大多数情况下不会完全对齐,即使第一个小数位匹配也是如此。
ggplot() +
geom_segment(data = data_fine, color = "gray70",
aes(x = t_fine, xend = t_fine, y = 0, yend = value_fine)) +
geom_segment(data = data_coarse,
aes(x = t_coarse, xend = t_coarse, y = 0, yend = value_coarse))
如果您的数据很小,将这些排列成最接近匹配的一种蛮力方法是计算所有成对时间距离,select 计算每个时间距离的最佳值。如果您的数据超过 10k 行,我预计这会开始变得太低效,并且在 data.table
.
library(tidyverse)
crossing(data_fine, data_coarse) %>% # from tidyr, incl in tidyverse
mutate(t_diff = abs(t_coarse - t_fine)) %>%
group_by(t_fine) %>%
slice_min(t_diff) %>%
ungroup()
## A tibble: 26 x 5
# t_fine value_fine t_coarse value_coarse t_diff
# <dbl> <int> <dbl> <int> <dbl>
# 1 50 1 50 1 0
# 2 50.0 2 50 1 0.0417
# 3 50.1 3 50.1 2 0.0278
# 4 50.1 4 50.1 2 0.0139
# 5 50.2 5 50.1 2 0.0556
# 6 50.2 6 50.2 3 0.0139
# 7 50.2 7 50.2 3 0.0278
# 8 50.3 8 50.3 4 0.0417
# 9 50.3 9 50.3 4 0
#10 50.4 10 50.3 4 0.0417
## … with 16 more rows
这里有一张图可以直观地检查结果:
ggplot() +
geom_segment(data = data_fine, color = "gray70",
aes(x = t_fine, xend = t_fine, y = 0, yend = value_fine)) +
geom_segment(data = data_tot, color = "red", # This is output of prior chunk
aes(x = t_fine, xend = t_coarse, y = 0, yend = value_coarse)) +
geom_segment(data = data_coarse,
aes(x = t_coarse, xend = t_coarse, y = 0, yend = value_coarse))