【问题标题】:Merging different length data frames with their mean values in the overlapping observations在重叠观察中合并不同长度的数据帧及其平均值
【发布时间】:2015-11-12 22:10:23
【问题描述】:

例如,我有 3 个数据框:

test.df1
        date  x  y  z
1 1998-01-01 10 10 10
2 1998-02-01 10 10 10
3 1998-03-01 10 10 10
4 1998-04-01 10 10 10
5 1998-05-01 10 10 10
6 1998-06-01 10 10 10

test.df2
        date x y z
1 1998-03-01 5 5 5
2 1998-04-01 5 5 5
3 1998-05-01 5 5 5
4 1998-06-01 5 5 5

test.df3
        date x y z
1 1998-05-01 1 1 1
2 1998-06-01 1 1 1

我想将它们合并在一起,以便新数据框的行数与最大数据框中的行数相同(在此示例中为test.df1),并且当日期重叠时,添加变量的平均值到新的数据框。在上面的示例中,新数据框应该有4 列和6 行。

xyz 对于 1998-01-011998-02-01 应保留为 10

对于1998-03-011998-06-01 应该是7.5(10 + 5 的平均值);

对于1998-05-011998-06-01 应该是5.33(10 + 5 + 1 的平均值)

有没有办法在 r 中做到这一点?

dput(test.df1)
structure(list(date = structure(c(10227, 10258, 10286, 10317, 
10347, 10378), class = "Date"), x = c(10, 10, 10, 10, 10, 10), 
y = c(10, 10, 10, 10, 10, 10), z = c(10, 10, 10, 10, 10, 
10)), .Names = c("date", "x", "y", "z"), row.names = c(NA, 
-6L), class = "data.frame")

dput(test.df2)
structure(list(date = structure(c(10286, 10317, 10347, 10378), class = "Date"), 
x = c(5, 5, 5, 5), y = c(5, 5, 5, 5), z = c(5, 5, 5, 5)), .Names = c("date", 
"x", "y", "z"), row.names = c(NA, -4L), class = "data.frame")

dput(test.df3)
structure(list(date = structure(c(10347, 10378), class = "Date"), 
x = c(1, 1), y = c(1, 1), z = c(1, 1)), .Names = c("date", 
"x", "y", "z"), row.names = c(NA, -2L), class = "data.frame")

【问题讨论】:

  • 可以做到,但是我能想到的唯一方法是相当复杂。我将查询每个数据框元素以查找匹配的日期字符串字段,并根据所有匹配项的平均值构造一个新数据框。它相当直接的数据框架工作。
  • 答案:是的,这可以在 R 中完成。

标签: r rbind


【解决方案1】:

我的方法是首先将数据帧与重复项绑定,然后使用 dplyr 包(在执行 colMeans 时,请确保排除非数字列):

library(plyr)
test.merge <- rbind(test.df1, test.df2, test.df3)
test.merge <- ddply(test.merge, ~date, function(x){
  colMeans(x[,-1])
})

输出

        date         x         y         z
1 1998-01-01 10.000000 10.000000 10.000000
2 1998-02-01 10.000000 10.000000 10.000000
3 1998-03-01  7.500000  7.500000  7.500000
4 1998-04-01  7.500000  7.500000  7.500000
5 1998-05-01  5.333333  5.333333  5.333333
6 1998-06-01  5.333333  5.333333  5.333333

【讨论】:

    【解决方案2】:

    base R 中的一个班轮应该可以带你到达那里:

    aggregate(. ~ date, data=rbind(test.df1,test.df2,test.df3), FUN=mean)
    #        date         x         y         z
    #1 1998-01-01 10.000000 10.000000 10.000000
    #2 1998-02-01 10.000000 10.000000 10.000000
    #3 1998-03-01  7.500000  7.500000  7.500000
    #4 1998-04-01  7.500000  7.500000  7.500000
    #5 1998-05-01  5.333333  5.333333  5.333333
    #6 1998-06-01  5.333333  5.333333  5.333333
    

    使用rbind 将所有行设为一个大data.frame,然后按日期创建aggregate,以便在有重叠时计算平均值。

    如果您是dplyr 用户,可以应用相同的逻辑:

    library(dplyr)    
    rbind_all(list(test.df1,test.df2,test.df3)) %>% 
      group_by(date) %>% 
      summarise_each(funs(mean))
    

    【讨论】:

      【解决方案3】:

      我们可以使用dplyrtidyr

      library(dplyr)
      library(tidyr)
      test.df1 %>% left_join(test.df2, by = "date") %>%
                   left_join(test.df3, by = "date") %>%
                   gather(var, val, -date) %>%
                   mutate(var = substr(var, 1, 1)) %>%
                   group_by(date, var) %>%
                   summarise(val = mean(val, na.rm = TRUE)) %>%
                   spread(var, val)
      Source: local data frame [6 x 4]
      
              date         x         y         z
            (date)     (dbl)     (dbl)     (dbl)
      1 1998-01-01 10.000000 10.000000 10.000000
      2 1998-02-01 10.000000 10.000000 10.000000
      3 1998-03-01  7.500000  7.500000  7.500000
      4 1998-04-01  7.500000  7.500000  7.500000
      5 1998-05-01  5.333333  5.333333  5.333333
      6 1998-06-01  5.333333  5.333333  5.333333
      

      【讨论】:

        猜你喜欢
        • 2012-12-15
        • 2021-02-26
        • 2020-04-10
        • 2019-02-27
        • 1970-01-01
        • 2015-11-28
        • 1970-01-01
        • 1970-01-01
        • 2015-04-04
        相关资源
        最近更新 更多