【问题标题】:Calculate statistic (e.g sum, mean...) base on columns from another dataset根据来自另一个数据集的列计算统计数据(例如总和、平均值...)
【发布时间】:2021-03-14 02:06:31
【问题描述】:

我有这两个数据集

   Week Year     value   min_date
1     5 2019 0.2544485 2019-01-29
2     6 2019 0.4517341 2019-02-05
3     7 2019 0.3850368 2019-02-12
4     8 2019 0.2638608 2019-02-19
5     9 2019 0.4701723 2019-02-26
6    10 2019 0.4299216 2019-03-05
7    11 2019 0.3539982 2019-03-12
8    12 2019 0.3121920 2019-03-19
9    13 2019 0.4851671 2019-03-26
10   14 2019 0.3682839 2019-04-02
11   15 2019 0.3118504 2019-04-09
12   16 2019 0.5535208 2019-04-16
13   17 2019 0.5439670 2019-04-23
14   18 2019 0.2279846 2019-04-30
15   19 2019 0.9141420 2019-05-07

   open_window close_window      ID Week
1   2019-02-02   2019-04-06  19-100    5
2   2009-03-04   2009-05-06  09-414    9
3   2004-03-06   2004-05-08  04-334   10
4   2004-02-24   2004-04-27  04-076    8
5   2007-02-16   2007-04-20  07-603    7
6   2012-12-25   2013-02-26  13-706   52
7   2018-03-31   2018-06-02 18-1197   13
8   2008-03-03   2008-05-05  08-415    9
9   2008-02-01   2008-04-04  08-922    5
10  2007-03-14   2007-05-16  07-292   11

我想向第二个数据集添加一列,其中包含日期 open_window 和 close_window 之间的第一个数据集的平均值。例如,在第一行中,预计平均值 = 0.3911519(从第 2 行到第 10 行的所有值的平均值)。

谢谢!!

数据:

Dates = structure(list(Week = 5:19, Year = c(2019L, 2019L, 2019L, 2019L, 
2019L, 2019L, 2019L, 2019L, 2019L, 2019L, 2019L, 2019L, 2019L, 
2019L, 2019L), value = c(0.254448507, 0.45173412229249, 0.385036779948187, 
0.263860826315789, 0.470172300321285, 0.429921606571429, 0.35399815840708, 
0.312191999393939, 0.485167061091703, 0.368283872580645, 0.311850394166667, 
0.553520780789474, 0.54396702, 0.227984592352941, 0.914141983686275
), min_date = structure(c(17925, 17932, 17939, 17946, 17953, 
17960, 17967, 17974, 17981, 17988, 17995, 18002, 18009, 18016, 
18023), class = "Date")), class = "data.frame", row.names = c(NA, 
-15L))

Data = structure(list(open_window = structure(c(17929, 14307, 12483, 
12472, 13560, 15699, 17621, 13941, 13910, 13586), class = "Date"), 
    close_window = structure(c(17992, 14370, 12546, 12535, 13623, 
    15762, 17684, 14004, 13973, 13649), class = "Date"), ID = c("19-100", 
    "09-414", "04-334", "04-076", "07-603", "13-706", "18-1197", 
    "08-415", "08-922", "07-292"), Week = c(5, 9, 10, 8, 7, 52, 
    13, 9, 5, 11)), row.names = c(NA, -10L), class = "data.frame")

【问题讨论】:

  • 我认为data.table 的非 equi 连接会是最快的。请参阅此示例 stackoverflow.com/questions/64202974/… 而不是 sum 使用 mean
  • 是的!谢谢,我认为这可行。只是出于好奇,有没有办法用 tidyverse 做到这一点?

标签: r date dplyr tidyverse


【解决方案1】:

基础 R 解决方案:

# Apply using row-number of df2:  
df2$avg <- sapply(seq_len(nrow(df2)), function(i) {
  mean(with(df1, value[min_date >= df2$open_window[i] & (min_date + 6) <= df2$close_window[i]]))
  }
)

数据:

df1 <- structure(list(Week = 5:19, Year = c(2019L, 2019L, 2019L, 2019L, 
2019L, 2019L, 2019L, 2019L, 2019L, 2019L, 2019L, 2019L, 2019L, 
2019L, 2019L), value = c(0.2544485, 0.4517341, 0.3850368, 0.2638608, 
0.4701723, 0.4299216, 0.3539982, 0.312192, 0.4851671, 0.3682839, 
0.3118504, 0.5535208, 0.543967, 0.2279846, 0.914142), min_date = structure(c(17925, 
17932, 17939, 17946, 17953, 17960, 17967, 17974, 17981, 17988, 
17995, 18002, 18009, 18016, 18023), class = "Date")), row.names = c(NA, -15L), class = "data.frame")

df2 <- structure(list(open_window = structure(c(17929, 14307, 12483, 
12472, 13560, 15699, 17621, 13941, 13910, 13586), class = "Date"), 
close_window = structure(c(17992, 14370, 12546, 12535, 13623, 
15762, 17684, 14004, 13973, 13649), class = "Date"), ID = c("19-100", 
"09-414", "04-334", "04-076", "07-603", "13-706", "18-1197", 
"08-415", "08-922", "07-292"), Week = c(5L, 9L, 10L, 8L, 
7L, 52L, 13L, 9L, 5L, 11L), avg = c(0.3940103625, NaN, NaN, 
NaN, NaN, NaN, NaN, NaN, NaN, NaN)), row.names = c(NA, -10L
), class = "data.frame")

【讨论】:

    【解决方案2】:

    tidyverse 的解决方案是:

    library(dplyr)
    
    Dates %>%
      select(-Week, -Year) %>%
      tidyr::crossing(Data %>% select(-Week)) %>%
      filter(min_date >= open_window, min_date <= close_window) %>%
      group_by(ID) %>%
      summarise(value = mean(value))
    

    【讨论】:

      【解决方案3】:

      其他解决方案

         Data %>% 
            rowwise() %>% 
            mutate(out = list(Dates$value[Dates$min_date %within% interval(open_window, close_window)])) %>% 
            ungroup() %>% 
            mutate(res = map_dbl(out, mean, na.rm = T)) %>% 
            select(-out)
      
      # A tibble: 10 x 5
         open_window close_window ID       Week     res
         <date>      <date>       <chr>   <dbl>   <dbl>
       1 2019-02-02  2019-04-06   19-100      5   0.391
       2 2009-03-04  2009-05-06   09-414      9 NaN    
       3 2004-03-06  2004-05-08   04-334     10 NaN    
       4 2004-02-24  2004-04-27   04-076      8 NaN    
       5 2007-02-16  2007-04-20   07-603      7 NaN    
       6 2012-12-25  2013-02-26   13-706     52 NaN    
       7 2018-03-31  2018-06-02   18-1197    13 NaN    
       8 2008-03-03  2008-05-05   08-415      9 NaN    
       9 2008-02-01  2008-04-04   08-922      5 NaN    
      10 2007-03-14  2007-05-16   07-292     11 NaN  
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-11
        • 2020-03-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多