【问题标题】:Sums for certain colums and whole dataframe某些列和整个数据框的总和
【发布时间】:2021-04-28 10:29:09
【问题描述】:

我想分析气象数据并找出一个站 (Xn) 每年超过某个阈值的频率,并且对于整个数据框也是如此(所以我每年得到一个值)。 我用 Aggregate 和 Dplyr 尝试了一些东西,但它并没有真正起作用。

所以首先我给你我的数据框(它只是一个虚拟的 DF,原来的有大约 80 列和 10000 行):

set.seed(123)
df1<-data.frame(replicate(6,sample(0:200,1500,rep=TRUE)))
date_df1<-seq(as.Date("1995-01-01"), by = "day", length.out = 1500)
test_sto<-cbind(date_df1, df1)
test_sto$date_df1<-as.Date(test_sto$date_df1)
test_sto<-test_sto%>%    dplyr::mutate(     year = lubridate::year(date_df1), 
                                    month = lubridate::month(date_df1),
                                    day = lubridate::day(date_df1))

     date_df1  X1  X2  X3  X4  X5  X6 year month day
1 1995-01-01 158 149  51 136  70 140 1995     1   1
2 1995-01-02 178 135 134 109  38 144 1995     1   2
3 1995-01-03  13  64  70 148 177 130 1995     1   3

首先,我尝试了聚合函数,结果如下:

aggregate.data.frame(x=test_sto[2:7] > 120, by = list(test_sto$year), FUN = sum, na.rm=TRUE )

 Group.1  X1  X2  X3  X4  X5  X6
1    1995 143 141 159 152 147 144
2    1996 153 141 148 153 160 165
3    1997 148 126 150 149 139 153

这适用于每个站,但我如何获得整个数据框每年的超过?

我尝试了以下

aggregate.data.frame(x=test_sto[2:7] > 120, by = list(test_sto$year), FUN = colSums(test_sto[2:7] > 120, na.rm = TRUE), na.rm=TRUE )

但这显然不起作用,但我无法弄清楚如何将 colSums 之类的东西放入此函数中。

我的第二种方法是使用 dplyr,但在这里我正在努力使用我认为的语法:

test_sto %>% group_by(year) %>% 
  summarise_all(funs((colSums(test_sto[2:7] > 120, na.rm=TRUE))))

   year date_df1    X1    X2    X3    X4    X5    X6 month   day
   <dbl>    <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
 1  1995      601   601   601   601   601   601   601   601   601
 2  1995      576   576   576   576   576   576   576   576   576
 3  1995      610   610   610   610   610   610   610   610   610
 4  1995      622   622   622   622   622   622   622   622   622
 5  1995      610   610   610   610   610   610   610   610   610
 6  1995      616   616   616   616   616   616   616   616   616
 7  1996      601   601   601   601   601   601   601   601   601
 8  1996      576   576   576   576   576   576   576   576   576
 9  1996      610   610   610   610   610   610   610   610   610
10  1996      622   622   622   622   622   622   622   622   622

每列都有相同的值,这绝对是不正确的,但我找不到我的错误。而且年份也不正确。 这里的目标和上面一样,一个站多长时间超过阈值和整个数据帧都一样。

【问题讨论】:

  • 提示:没有set.seed(),您的输出将无法重现
  • 我必须将 set.seed() 放在哪里?比如:df1
  • df1&lt;-data.frame(replicate(6,sample(0:200,1500,rep=TRUE)))上方的单独行中。这样可以确保sample() 函数的结果始终相同,因此每个人都可以尝试产生与您想要的输出相同的答案。
  • 添加行set.seed(123),并相应地更新[更新您想要的输出。

标签: r dplyr aggregate


【解决方案1】:

使用tidyverse,您可以执行以下操作:

library(tidyverse)

test_sto %>%
  group_by(year) %>%
  summarise(across(starts_with("X"), ~sum(. > 120)))

输出

   year    X1    X2    X3    X4    X5    X6
  <dbl> <int> <int> <int> <int> <int> <int>
1  1995   143   141   159   152   147   144
2  1996   153   141   148   153   160   165
3  1997   148   126   150   149   139   153
4  1998   144   150   138   152   145   138
5  1999    13    18    15    16    19    16

对于每年的所有电台,只需在pivot_longer 输入长格式后group_by(year)

test_sto %>%
  pivot_longer(cols = starts_with("X")) %>%
  group_by(year) %>%
  summarise(gtr_120 = sum(value > 120))

输出

   year gtr_120
  <dbl>   <int>
1  1995     886
2  1996     920
3  1997     865
4  1998     867
5  1999      97

【讨论】:

    【解决方案2】:

    不确定,但我相信这就是您要找的东西?

    library(data.table)
    # make it a data.table
    setDT(test_sto)
    
    # part 1: >120 by year
    test_sto[, lapply(.SD, function(x) sum(x > 120)), 
               by = .(year), 
               .SDcols = patterns("^X")]
    #    year  X1  X2  X3  X4  X5  X6
    # 1: 1995 143 141 159 152 147 144
    # 2: 1996 153 141 148 153 160 165
    # 3: 1997 148 126 150 149 139 153
    # 4: 1998 144 150 138 152 145 138
    # 5: 1999  13  18  15  16  19  16
    
    # part 2: totals >120 by station over all years
    test_sto[, lapply(.SD, function(x) sum(x > 120)), 
             .SDcols = patterns("^X")]
    #     X1  X2  X3  X4  X5  X6
    # 1: 601 576 610 622 610 616
    

    【讨论】:

    • 谢谢!是的,第一部分看起来不错。但是对于第 2 部分,我正在寻找整个数据框每年超过的阈值,例如每年一个值。 sum(colSums(test_sto[2:7] > 120, na.rm=TRUE))-> 这样我得到每个站组合的阈值超过的数量,但我每年都需要它
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-31
    • 2015-09-16
    • 1970-01-01
    • 1970-01-01
    • 2018-04-25
    • 1970-01-01
    相关资源
    最近更新 更多