将数据框中的日期与R中列表中最接近的日期进行匹配

问题描述 投票:0回答:1

我有一个包含日期列表的数据框。我还有一个向量形式的参考日期列表。我创建了一个可复制的数据框和向量。除了创建日期框之外,您可以忽略“r”对象。

i=500;j=500;n=50
r <- do.call(stack, replicate(n,raster(matrix(runif(i*j), i, j))))
( dates <- seq(as.Date("2020/10/23"), by = 16, length.out = 20) ) 

s <- as(sampleRandom(r[[1]], 100, sp=TRUE), "sf")
df <-  as.data.frame(s)
df$date <- sample(dates, nrow(s), replace=TRUE)

我想找到每个数据框行中距离最近的向量日期最近的日期。然后在数据框中的新列中返回最接近的向量日期。

作为参考,我将使用它来将矢量日期与栅格堆栈中的相应栅格进行匹配,并根据日期进行提取。这就是为什么 's' 最初是 'sf' 类型,而我也有 'r' 对象。

r date geospatial lubridate
1个回答
0
投票

要实现这一点,您必须决定是否寻找 过去、未来或两者的最近日期。如果您选择两者,则需要 决定如果两个日期距离相同该怎么办。

这里有两种方法。

  1. 执行
    left_join()
    并在
    closest()
    中使用
    join_by()
  2. 编写自定义函数来查找最接近的日期。

两种方法的数据准备。

# Boiled down example of what you describe in your question.

library(tidyverse)

dates <- seq(as.Date("2020/10/23"),
             by = 16,
             length.out = 20)
dates2 <- sample(dates, 10)
df <- tibble(date = sample(dates, 30, replace = TRUE))

1.
closest()
join_by()

这会寻找一个方向上最接近的日期。

ref_df <-
  tibble(date_vector = dates2)

left_join(df, ref_df,
          by = join_by(closest(date <= date_vector)),
          keep = TRUE)
#> # A tibble: 30 × 2
#>    date       date_vector
#>    <date>     <date>     
#>  1 2020-12-26 2020-12-26 
#>  2 2020-10-23 2020-11-08 
#>  3 2021-07-22 2021-08-23 
#>  4 2021-03-16 2021-03-16 
#>  5 2021-04-17 2021-05-03 
#>  6 2021-04-17 2021-05-03 
#>  7 2021-04-17 2021-05-03 
#>  8 2021-04-17 2021-05-03 
#>  9 2021-01-11 2021-03-16 
#> 10 2020-12-26 2020-12-26 
#> # ℹ 20 more rows

如果我们想从两个方向看,我们可以这样做:

left_join(df, ref_df,
          by = join_by(closest(date <= date_vector)),
          keep = TRUE) |>
  left_join(ref_df,
            by = join_by(closest(date >= date_vector)),
            keep = TRUE) |>
  # Reverse the order of date_vector.x and date_vector.y in the
  # coalesce() call to decide which direction to prefer.
  mutate(closest_date = coalesce(date_vector.x, date_vector.y))
#> # A tibble: 30 × 4
#>    date       date_vector.x date_vector.y closest_date
#>    <date>     <date>        <date>        <date>      
#>  1 2020-12-26 2020-12-26    2020-12-26    2020-12-26  
#>  2 2020-10-23 2020-11-08    NA            2020-11-08  
#>  3 2021-07-22 2021-08-23    2021-07-06    2021-08-23  
#>  4 2021-03-16 2021-03-16    2021-03-16    2021-03-16  
#>  5 2021-04-17 2021-05-03    2021-03-16    2021-05-03  
#>  6 2021-04-17 2021-05-03    2021-03-16    2021-05-03  
#>  7 2021-04-17 2021-05-03    2021-03-16    2021-05-03  
#>  8 2021-04-17 2021-05-03    2021-03-16    2021-05-03  
#>  9 2021-01-11 2021-03-16    2020-12-26    2021-03-16  
#> 10 2020-12-26 2020-12-26    2020-12-26    2020-12-26  
#> # ℹ 20 more rows

2.自定义功能

自定义函数看起来是双向的。

# Function that finds the closest date in a vector of dates.
find_closest_date <- function(date, date_vector)
{
  date_vector <- unique(date_vector)
  diffs <- abs(date - date_vector)
  
  # Two dates in date_vector can have the same distance to date, by adding
  # `[1]` we pick whichever comes first in date_vector.
  date_vector[diffs == min(diffs)][1]
}

# Test the function for one date.
find_closest_date(dates[1], dates2)
#> [1] "2020-11-08"

# Apply function to all dates.

df |>
  mutate(closest_date = map(date, find_closest_date, dates2) |>
           list_simplify())
#> # A tibble: 30 × 2
#>    date       closest_date
#>    <date>     <date>      
#>  1 2020-12-26 2020-12-26  
#>  2 2020-10-23 2020-11-08  
#>  3 2021-07-22 2021-07-06  
#>  4 2021-03-16 2021-03-16  
#>  5 2021-04-17 2021-05-03  
#>  6 2021-04-17 2021-05-03  
#>  7 2021-04-17 2021-05-03  
#>  8 2021-04-17 2021-05-03  
#>  9 2021-01-11 2020-12-26  
#> 10 2020-12-26 2020-12-26  
#> # ℹ 20 more rows
© www.soinside.com 2019 - 2024. All rights reserved.