【问题标题】:Calculate monthly sums for multiple columns计算多列的每月总和
【发布时间】:2019-10-01 14:10:33
【问题描述】:

我有一个数据框,第一列包含年份,第二列包含月份,第三列包含天数,第四列和第五列包含不同城市(伦敦和纽约)的降雨量数据,如下所示:

mat1 = matrix(c(rep(1979, each=360), rep(1:12, each=30), rep(seq(1, 30, by=1), times=12), 
            rep(seq(5, 25, by=5), times=72), rep(seq(1, 9, by=1), times=40)), nrow=360, ncol=5)

colnames(mat1) = c("Year", "Month", "Day", "LON", "NYC")

我想计算每个城市的每月总和。输出应采用以下形式:

    LON NYC
Jan  x   x
Feb  x   x
Mar  x   x
................

我试过了:

aggregate(LON ~ Month + Year, mat1, sum)

但这不会以我想要的格式输出数据,而且至关重要的是,它也只允许我一次计算一个城市(列)。如何调整上述内容以适用于所有城市并以所需格式输出?

【问题讨论】:

  • 在一栏(从宽到长)、分组、汇总中获取所有城市?
  • aggregate(cbind(LON, NYC) ~ Month + Year, mat1, sum) 或根据您的需要省略年份。

标签: r


【解决方案1】:

使用dplyr 的解决方案。在使用group_bysummarize_at函数之前,我们需要将矩阵转换为数据框。

library(dplyr)
mat1_sum <- mat1 %>%
  as.data.frame() %>%
  group_by(Month) %>%
  summarize_at(vars(LON, NYC), sum)
mat1_sum
# # A tibble: 12 x 3
#    Month   LON   NYC
#    <dbl> <dbl> <dbl>
#  1     1   450   141
#  2     2   450   150
#  3     3   450   159
#  4     4   450   141
#  5     5   450   150
#  6     6   450   159
#  7     7   450   141
#  8     8   450   150
#  9     9   450   159
# 10    10   450   141
# 11    11   450   150
# 12    12   450   159

【讨论】:

  • 这很好用——非常感谢@www。实际上我有几十个城市,所以有没有办法修改 summarise_at 以包括所有城市?
  • @DJ-AFC 可能是mat1_sum &lt;- mat1 %&gt;% as.data.frame() %&gt;% group_by(Month, Cities) %&gt;% summarize_at(vars(LON, NYC), sum)
【解决方案2】:

可以说是复杂的事情,但dplyr-tidyr 选项。这使用较新的pivot_* 函数代替gather/spread。 @www 显示的纯 dplyr 选项可能更有效。

as.data.frame(mat1) %>% 
   pivot_longer(LON:NYC,names_to = "city")  %>% 
   group_by(Year,Month,city) %>% 
   summarise(Sum = sum(value)) %>% 
   pivot_wider(names_from = city,values_from = Sum)
# A tibble: 12 x 4
# Groups:   Year, Month [12]
    Year Month   LON   NYC
   <dbl> <dbl> <dbl> <dbl>
 1  1979     1   450   141
 2  1979     2   450   150
 3  1979     3   450   159
 4  1979     4   450   141
 5  1979     5   450   150
 6  1979     6   450   159
 7  1979     7   450   141
 8  1979     8   450   150
 9  1979     9   450   159
10  1979    10   450   141
11  1979    11   450   150
12  1979    12   450   159

【讨论】:

  • 谢谢。我选择了@www 的解决方案,但上面是另一个不错的解决方案
【解决方案3】:

像这样?

> aggregate(mat1[,4:5],list(mat1[,2]),sum)
   Group.1 LON NYC
1        1 450 141
2        2 450 150
3        3 450 159
4        4 450 141
5        5 450 150
6        6 450 159
7        7 450 141
8        8 450 150
9        9 450 159
10      10 450 141
11      11 450 150
12      12 450 159

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-17
    • 1970-01-01
    • 2014-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多