使用不同 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))