【问题标题】:calculating summary statistics for multiple ranges in data frame计算数据框中多个范围的汇总统计
【发布时间】:2018-03-05 21:49:04
【问题描述】:

我有一个大数据框“表”为:

  Year Month        Model Scenario Longitude Latitude tas_month pr_month
1 2000     1 ccsm4_r1i1p1    rpc45      9.57   -84.53     24.20    40.63
2 2000     2 ccsm4_r1i1p1    rpc45      9.57   -84.53     25.05    54.20
3 2000     3 ccsm4_r1i1p1    rpc45      9.57   -84.53     25.19    36.87
4 2000     4 ccsm4_r1i1p1    rpc45      9.57   -84.53     25.44   126.47
5 2000     5 ccsm4_r1i1p1    rpc45      9.57   -84.53     25.36   282.44
6 2000     6 ccsm4_r1i1p1    rpc45      9.57   -84.53     25.71   284.68

并且我想使用group_by(Month, Longitude, Latitude, Model, Scenario) 创建一个新的数据框,该数据框在五年内的每个时期都具有mean(tas_month)mean(pr_month)。这个新数据框还必须有一个新列,其中每一行都有这些值所属的 5 年期间的值。

  Period Month        Model Scenario Longitude Latitude tas_month pr_month
1 1     1 ccsm4_r1i1p1    rpc45      9.57   -84.53     24.20    40.63
2 2     2 ccsm4_r1i1p1    rpc45      9.57   -84.53     25.05    54.20
3 3     3 ccsm4_r1i1p1    rpc45      9.57   -84.53     25.19    36.87
4 4     4 ccsm4_r1i1p1    rpc45      9.57   -84.53     25.44   126.47
5 5     5 ccsm4_r1i1p1    rpc45      9.57   -84.53     25.36   282.44
6 6     6 ccsm4_r1i1p1    rpc45      9.57   -84.53     25.71   284.68

我已经创建了一个以五年为周期的向量:

fiveyears <- seq(2000, 2100, 5)

但仍然无法弄清楚如何计算平均值。我在想这样的“伪”代码,但它仍然很粗糙:

for (i in seq_along(fiveyears)){
  table %>% filter(Year < (i+5) & Year >= i) %>% 
  group_by(Month, Longitude, Latitude, Model, Scenario) %>% 
  summarise(pr_month = mean(pr_month), tas_month = mean(tas_month))

非常感谢任何帮助。

【问题讨论】:

    标签: r loops dplyr


    【解决方案1】:

    您的示例数据仅涉及 2000 年,因此我们可以使用以下内容:

    df <- data.frame(Year = rep(2000:2011, each = 3), x = rnorm(36))
    

    你的想法不错,但我们可以让它更简洁:

    df %>% group_by(Year %/% 5) %>% summarize(y = mean(x))
    # A tibble: 3 x 2
    #   `Year%/%5`      y
    #        <dbl>  <dbl>
    # 1        400  0.334
    # 2        401  0.116
    # 3        402 -0.222
    

    其中%/% 表示整数除法。如果需要,您可以更改第一列名称并相应地对其值进行规范化。

    更新:

    df %>% group_by(Year %/% 5, Month, Longitude, Latitude, Model, Scenario) %>% 
      summarize(tas_month = mean(tas_month), pr_month = mean(pr_month)) %>% 
      rename("Period" = `Year%/%5`) %>% 
      transform(Period = Period - min(df$Year %/% 5) + 1)
    #   Period Month Longitude Latitude        Model Scenario tas_month pr_month
    # 1      1     1      9.57   -84.53 ccsm4_r1i1p1    rpc45     24.20    40.63
    # 2      1     2      9.57   -84.53 ccsm4_r1i1p1    rpc45     25.05    54.20
    # 3      1     3      9.57   -84.53 ccsm4_r1i1p1    rpc45     25.19    36.87
    # 4      1     4      9.57   -84.53 ccsm4_r1i1p1    rpc45     25.44   126.47
    # 5      1     5      9.57   -84.53 ccsm4_r1i1p1    rpc45     25.36   282.44
    # 6      1     6      9.57   -84.53 ccsm4_r1i1p1    rpc45     25.71   284.68
    

    【讨论】:

    • 谢谢!它工作得很好。我最终花了一些时间弄清楚如何更改第一列的值。我在你之后写了我的答案。我想它可以用更少的行来写……我希望有一天……
    • @Guillermo.D,查看更新,我试图获得您想要的结果,希望它也适用于您的完整数据集。也许Period 不是你想要的?我假设它只描述了 5 年期间,不涉及任何其他变量。
    【解决方案2】:

    按照@Julius 的建议,我最终得到了这个。不像我想要的那样干净或优雅,但至少我希望它能给遇到类似问题的人一些想法:

    tbl_month_5years <- table %>% 
      group_by(Year %/% 5, Month, Longitude, Latitude, Model, Scenario) %>%
      summarise(tas_mean = mean(tas_month), pr_mean = mean(pr_month)) %>%
      rename(period = `Year%/%5`)
    
    periods_5years <- tbl_month_5years %>% group_by(period) %>%    
      summarise(n())
    
    years5 <- as.data.frame(seq(2000, 2095, 5))
    years5 <-years5 %>% rename(ini_year = `seq(2000, 2095, 5)`)
    years5 <- cbind(years5, periods_5years)
    
    tbl_month_5years <- tbl_month_5years %>% 
      left_join(years5, by = "period") %>% select(-`n()`)
    

    【讨论】:

      猜你喜欢
      • 2019-08-18
      • 2014-04-09
      • 2015-07-18
      • 2018-11-11
      • 2016-10-12
      • 1970-01-01
      • 1970-01-01
      • 2023-01-05
      • 1970-01-01
      相关资源
      最近更新 更多