R объединение данных на основе ближайшей даты и при соблюдении условий

#r #date #join #merge

Вопрос:

Я хочу выполнить левое соединение с двумя данными.фреймами по df1$plots = df2$plots И ближайшей дате. Некоторые номера графиков обоих данных.кадры также повторяются, как в этом примере:

 df1=data.frame(plots=c(1,2,3,4,1),dates=as.POSIXct(c('01.01.2021','01.02.2021','01.03.2021','01.04.2021','02.01.2021'),format='%d.%m.%Y'))

df1
  plots      dates
1     1 2021-01-01
2     2 2021-02-01
3     3 2021-03-01
4     4 2021-04-01
5     1 2021-01-02

df2=data.frame(plots=c(1,2,3,4,1,2,3,4),dates=as.POSIXct(c('05.01.2021','02.02.2021','01.01.2021','29.03.2021','31.12.2020','17.06.2021','05.03.2021','08.02.2021'),format='%d.%m.%Y'),TargetValues=c(100:107) )

df2
  plots      dates TargetValues
1     1 2021-01-05          100
2     2 2021-02-02          101
3     3 2021-01-01          102
4     4 2021-03-29          103
5     1 2020-12-31          104
6     2 2021-06-17          105
7     3 2021-03-05          106
8     4 2021-02-08          107
 

Я бы хотел, чтобы df1 в конце концов выглядел так:

   plots      dates Values
1     1 2021-01-01    104
2     2 2021-02-01    101
3     3 2021-03-01    106
4     4 2021-04-01    103
5     1 2021-01-02    104
 

Это то, что я пытался:

 df1.2 <- lapply(intersect(df1$plots,df2$plots,function(id) {
  d1 <- subset(df1,plots==id)
  d2 <- subset(df2,plots==id)
  
  d1$indices <- sapply(d1$date,function(d) which.min(abs(d2$date - d)))
  d2$indices <- 1:nrow(d2)
  
  merge(d1,d2,by=c('plots','indices'))
}))
 

Но я получаю сообщение об ошибке «Ошибка в матче.весело(ВЕСЕЛО) : аргумент «ВЕСЕЛО» отсутствует, по умолчанию нет».

Как я могу исправить код или у кого-то есть другое представление о том, как выполнить задачу?

Ответ №1:

Вы можете объединить два plots фрейма данных и для каждого значения графиков и дат выбрать строку, которая имеет наименьшую абсолютную разницу.

 library(dplyr)

left_join(df1, df2, by = 'plots') %>%
  group_by(plots, dates.x) %>%
  slice(which.min(abs(dates.x - dates.y))) %>%
  ungroup %>%
  select(plots, dates = dates.x, TargetValues)

#  plots dates               TargetValues
#  <dbl> <dttm>                     <int>
#1     1 2021-01-01 00:00:00          104
#2     1 2021-01-02 00:00:00          104
#3     2 2021-02-01 00:00:00          101
#4     3 2021-03-01 00:00:00          106
#5     4 2021-04-01 00:00:00          103
 

Комментарии:

1. Спасибо! После того, как я это сделал, строки моего целевого фрейма данных уменьшились с 292 до 177. Знаете ли вы, почему и как это исправить? Изменить: Я изменил select (…) в конце на select_all, потому что я хочу видеть все данные из всех строк

2. У вас есть NA » в plots » или dates «колонка df1 «? Кроме того, если вы удалите select оператор al вместе, он выделит все столбцы.

3. Да, есть NA s внутри plots . Я удалил оператор select и закончил ungroup , но строки все еще уменьшаются. Могу я просто пропустить, когда NA появятся буквы s?

4. Уменьшение происходит после slice() аргумента