【问题标题】:Merge dataframes by rounding the dates通过四舍五入日期合并数据框
【发布时间】:2020-04-08 10:01:07
【问题描述】:

我想根据日期合并两个数据框,但它们的日期可能不同。基本上,当组日期对不完全匹配时,我想对日期进行四舍五入,以便第二个数据帧中的值与第一个数据帧中的值匹配,并尽可能接近日期。

为了更清楚,这里有一个例子:

library(dplyr)

data1 <- tibble(
  group = rep(c("A", "B"), each = 3),
  date = c(2002, 2005, 2010, 2001, 2004, 2009),
  variable_1 = c("Thing_1", "Thing_1", "Thing_2", "Thing_1", "Thing_2", "Thing_1")
)

# A tibble: 6 x 3
  group  date variable_1
  <chr> <dbl> <chr>     
1 A      2002 Thing_1   
2 A      2005 Thing_1   
3 A      2010 Thing_2   
4 B      2001 Thing_1   
5 B      2004 Thing_2   
6 B      2009 Thing_1   

data2 <- tibble(
  group = rep(c("A", "B"), each = 2),
  date = c(2007, 2008, 2001, 2010),
  variable_2 = c("Else_1", "Else_2", "Else_2", "Else_1")
)

  group  date variable_2
  <chr> <dbl> <chr>     
1 A      2007 Else_1    
2 A      2008 Else_2    
3 B      2001 Else_2    
4 B      2010 Else_1    

以 A 组为例,我们可以看到日期不相同:data1 的日期为 2002、2005 和 2010; data2 的 2007 年和 2008 年。因此,由于不可能完美匹配,我想“四舍五入”日期。 data2$date 为 2007 时的值应与 data1$date 为 2005 的值匹配,因为 2005 是最接近 2007 的值。同样,data2$date 为 2008 时的值应与 data1$date 的值匹配是 2010 年。

B 组也是如此。

这是预期的输出:

# A tibble: 6 x 4
  group  date variable_1 variable_2
  <chr> <dbl> <chr>      <chr>     
1 A      2002 Thing_1    NA        
2 A      2005 Thing_1    Else_1    
3 A      2009 Thing_2    Else_2    
4 B      2001 Thing_1    Else_2    
5 B      2004 Thing_2    NA        
6 B      2009 Thing_1    Else_1    

我该怎么做?

【问题讨论】:

    标签: r


    【解决方案1】:

    Map 方法中使用一些算术。由于日期是数字,因此以 5 为增量四舍五入很简单。我们在两个数据帧中都这样做,然后使用match

    res <- do.call(rbind, Map(function(x, y) {
      transform(x, variable_2=y$variable_2[
        match(round(x$date / 5)/.2, round(y$date / 5)/.2)
        ])},
      split(data1, data1$group), split(data2, data2$group)))
    res
    #     group date variable_1 variable_2
    # A.1     A 2002    Thing_1       <NA>
    # A.2     A 2005    Thing_1     Else_1
    # A.3     A 2010    Thing_2     Else_2
    # B.4     B 2001    Thing_1     Else_2
    # B.5     B 2004    Thing_2       <NA>
    # B.6     B 2009    Thing_1     Else_1
    

    【讨论】:

    • 我在理解您的代码时遇到了一些麻烦,这是特定于日期还是无论日期都有效吗?
    • 试试例如round(2002/5)/.2 给出 2000,或 round(2005/5)/.2 给出 2005,或 round(2009/5)/.2 给出 2010。
    【解决方案2】:

    您可以使用 data.table 包并检查滚动连接,roll="nearest" 可能会有所帮助

    【讨论】:

    • 你能告诉我我的例子吗?如果不是,请将此作为评论而不是答案
    【解决方案3】:
    data1 <- data.table(data1)
    data2 <- data.table(data2)
    setkey(data1, "date")
    setkey(data2, "date")
    
    data_a <- subset(data1,data1$group=="A")
    data_b <- subset(data2,data2$group=="A")
    
    data <- data_a[data_b, roll="TRUE"]
    

    【讨论】:

      猜你喜欢
      • 2014-05-05
      • 2020-08-04
      • 1970-01-01
      • 2015-03-03
      • 1970-01-01
      • 2023-01-03
      • 2015-06-14
      • 2021-12-16
      • 2015-11-12
      相关资源
      最近更新 更多