首页 > 解决方案 > 是否可以根据许多条件进行合并?

问题描述

我想要实现的是能够根据日期比较数据,如果日期在范围之间,则取最低的“PDF2”值。

这是我正在使用的两个数据框的示例。我想检查是否在“df2”的“R”列中找到来自“df”的“R”列的数据检查日期是否在 df2 的范围之间以及是否有任何冲突或重复我想要始终保持“PDF2”的最小值。

df <- data.frame("D" = c("01/01/2019", "01/02/2019", "01/03/2019", "01/12/2019"),
             "R" = c("ABC123", "ABC123", "ABC123", "ABC1"),
             "PDF" = c(1.23, 1.23, 1.23, 1.23),
             stringsAsFactors = FALSE)

df2 <- data.frame("DD" = c("01/01/2019", "01/02/2019", "01/01/2019"),
              "DF" = c("01/02/2019", "01/03/2019", "01/11/2019"),
              "R" = c("ABC123", "ABC123", "ABC1"),
              "PDF2" = c(1.12, 1.11, 1.12),
              stringsAsFactors = FALSE)

这是我期待的结果。

result <- data.frame("R" = c("ABC123", "ABC123", "ABC123"),
                 "D" = c("01/01/2019", "01/02/2019", "01/03/2019"),
                 "DD" = c("01/01/2019", "01/02/2019", "01/02/2019"),
                 "DF" = c("01/02/2019", "01/03/2019", "01/03/2019"),
                 "PDF" = c(1.23, 1.23, 1.23),
                 "PDF2" = c(1.12, 1.11, 1.11),
                 stringsAsFactors = FALSE)

如您所见,“ABC1”不在结果中,因为日期不在范围内。

我当前的问题是仅在日期范围存在重复或冲突时才保留最低值。

这是我当前代码的示例:

temp <- merge(df, df2, by = "R")
myd <- which(as.Date(temp$D, format = "%d/%m/%Y") <= as.Date(temp$DF, format = "%d/%m/%Y"))
myd2 <- which(as.Date(temp$D, format = "%d/%m/%Y") >= as.Date(temp$DD, format = "%d/%m/%Y"))
myd <- myd[myd %in% myd2]
if (length(myd)) {
  temp <- temp[myd,]
}

还有如何在单独的数据框中获得与要求不匹配的行?

标签: rdataframemerge

解决方案


我认为这个问题的答案可能会对您有所帮助:

如何根据来自另一个数据帧的许多行来查找数据帧中的一行的匹配项

df %>% 
  left_join(df2, by = "R") %>% 
  filter(lubridate::dmy(D) >= lubridate::dmy(DD) & lubridate::dmy(D) <= lubridate::dmy(DF)) %>% 
  group_by(R,D) %>% 
  filter(PDF2 == min(PDF2)) %>% 
  ungroup()

推荐阅读