1

我有一个降水数据库,其结构如下。

Season; YEAR; MONTH; DAY 01; DAY 02; DAY 03 ..... DAY 31 

数据在这里

起初我想计算每个月的累积(我使用区域计算),但只计算一个季节。现在我想做同样的事情,但是分离每个站点,除了更改数据库的结构之外,我还将获得每个站点的每日和每月值。第一列是日期,其他列是每个季节。

Date; season1; station2; estacao3 ....... estacaoN

01/01/1994;30;10;5;6
01/02/1994;10;12;55
.
.
.
.
.
.
.
31/07/2018
4

3 回答 3

1

首先,由于您的数据框非常重(我只在其中的一部分上运行代码),您可以使用fread函数打开它data.table(我将您的 xlsx 文件转换为 csv 文件)。

library(data.table)
df <- fread("../Dados_precipitacao.csv", skip = 2, header = TRUE)

long然后,您可以使用以下melt函数以某种格式重塑数据框data.table

library(data.table)
colonne <- grep("dia",colnames(df),value = TRUE)
dt.m <- melt(df, measure = list(colonne),value.name = "DIA")

现在,您有六列:

   Município/Posto  Bacia  Ano Mês variable DIA
1:     Agua Branca Piancó 1994   1    dia 1   0
2:     Agua Branca Piancó 1994   2    dia 1   0
3:     Agua Branca Piancó 1994   3    dia 1  20
4:     Agua Branca Piancó 1994   4    dia 1   0
5:     Agua Branca Piancó 1994   5    dia 1   0
6:     Agua Branca Piancó 1994   6    dia 1   0

现在,使用data.table,我们可以通过粘贴 Ano、Mes 和 Dia 创建一个日期列(Dia 将被修改以从字符串中删除“dia”),然后,我们将使用包中的ymd函数lubridate将这个字符串转换为数据格式:

library(data.table)
test <- dt.m[1:1000,]
test[, Day:=gsub("dia ","",variable)]
test[, Date := do.call(paste, c(.SD, sep = "-")), .SDcols = c("Ano","Mês","Day")]
test[, Date:= ymd(Date)]

      Município/Posto      Bacia  Ano Mês variable DIA Day       Date
   1:     Agua Branca     Piancó 1994   1    dia 1   0   1 1994-01-01
   2:     Agua Branca     Piancó 1994   2    dia 1   0   1 1994-02-01
   3:     Agua Branca     Piancó 1994   3    dia 1  20   1 1994-03-01
   4:     Agua Branca     Piancó 1994   4    dia 1   0   1 1994-04-01
   5:     Agua Branca     Piancó 1994   5    dia 1   0   1 1994-05-01
  ---                                                                
 996:     Alagoa Nova Mamanguape 2003   8    dia 1   0   1 2003-08-01
 997:     Alagoa Nova Mamanguape 2003   9    dia 1   0   1 2003-09-01
 998:     Alagoa Nova Mamanguape 2003  10    dia 1   0   1 2003-10-01
 999:     Alagoa Nova Mamanguape 2003  11    dia 1   0   1 2003-11-01
1000:     Alagoa Nova Mamanguape 2003  12    dia 1   0   1 2003-12-01

现在,我们可以使用函数dcastfromdata.table以更广泛的格式旋转数据表并为每个站点创建一列(这里我使用 Municipio/Posto):

library(data.table)
t <- dcast(test, value.var = "DIA", ... ~ `Município/Posto`)

          Bacia  Ano Mês variable Day       Date Agua Branca Aguiar Alagoa Grande Alagoa Nova
  1: Mamanguape 1994   1    dia 1   1 1994-01-01          NA     NA             0           0
  2: Mamanguape 1994   2    dia 1   1 1994-02-01          NA     NA             0           0
  3: Mamanguape 1994   3    dia 1   1 1994-03-01          NA     NA             0           0
  4: Mamanguape 1994   4    dia 1   1 1994-04-01          NA     NA             0           0
  5: Mamanguape 1994   5    dia 1   1 1994-05-01          NA     NA             0           0
 ---                                                                                         
584:     Piancó 2018   3    dia 1   1 2018-03-01         5.4      0            NA          NA
585:     Piancó 2018   4    dia 1   1 2018-04-01        12.6      0            NA          NA
586:     Piancó 2018   5    dia 1   1 2018-05-01        15.8     NA            NA          NA
587:     Piancó 2018   6    dia 1   1 2018-06-01         0.0     NA            NA          NA
588:     Piancó 2018   7    dia 1   1 2018-07-01         0.0     NA            NA          NA

希望这是您正在寻找的。

顺便说一句:如果您发布数据的可重现示例而不是插入指向完整数据集的链接(这非常繁重),这将使每个人的事情变得更容易。要知道如何做一个好的可重现示例:如何制作一个很棒的 R 可重现示例

于 2020-01-24T17:05:17.190 回答
0

此任务需要对数据集进行一些重塑,首先使其更长,然后再更宽。dc37 的答案已经描述了如何使用data.table. 我会推荐一种不同的方法,只使用tidyverse函数。

您说,您想计算每个站点每月降雨量的总和,对于该任务,实际上更容易将数据保持为长格式,而不是再次使其变宽。我将在下面演示这两个选项(2a 和 2b)。

我还建议不要合并日期变量,因为这使得按月对数据进行分组变得更加困难,或者我的方法是,您可以仅合并年份和月份,这仍然允许进行必要的分组。无论如何,2a) 演示了如何使用 tidyr::unite() 来合并日期变量。

1)将数据集转换为长格式

  library(tidyverse)
  library(readxl)
  rainfall_df <- read_excel("Dados_precipitacao.xls", skip = 2)

  rainfall_long_df <-
    rainfall_df %>%
    select(-Bacia) %>%
    pivot_longer(`dia 1`:`dia 31`, names_to = "dia") %>%
    mutate(dia = gsub("dia ", "", dia))

rain_long_df 看起来像这样:

 # A tibble: 1,931,889 x 5
   `Município/Posto`   Ano   Mês dia   value
   <chr>             <dbl> <dbl> <chr> <dbl>
 1 Agua Branca        1994     1 1       0  
 2 Agua Branca        1994     1 2       0  
 3 Agua Branca        1994     1 3       0  
 4 Agua Branca        1994     1 4       0  
 5 Agua Branca        1994     1 5       0  
 6 Agua Branca        1994     1 6       8.6
 7 Agua Branca        1994     1 7       0  
 8 Agua Branca        1994     1 8       2  
 9 Agua Branca        1994     1 9       0  
10 Agua Branca        1994     1 10      0  
# … with 1,931,879 more rows

2a)这就是您所要求的:从广泛的数据集中计算每月和站点的总和。

rainfall_wide_df <-   
  rainfall_long_df %>%
    unite(data, dia, Mês, Ano, sep = "/", remove = FALSE) %>%
    pivot_wider(names_from = `Município/Posto`)

rainfall_wide_df %>% 
    group_by(Ano, Mês) %>% 
    summarise_at(vars(`Agua Branca`:`Zabelê`), sum)

这导致:

# A tibble: 296 x 253
# Groups:   Ano [26]
     Ano   Mês `Agua Branca` Aguiar `Alagoa Grande` `Alagoa Nova` Alagoinha Alcantil `Algodão de Jan…
   <dbl> <dbl>         <dbl>  <dbl>           <dbl>         <dbl>     <dbl>    <dbl>            <dbl>
 1  1994     1         174.   442.            101            68.5      64.6       NA             NA  
 2  1994     2          NA     NA              NA            NA        NA         NA             NA  
 3  1994     3         285.   120.            239.          210.      213.        NA             NA  
 4  1994     4          NA     NA              NA            NA        NA         NA             NA  
 5  1994     5         176.    73.2           160.          233.      190         NA             41.8
 6  1994     6          NA     NA              NA            NA        NA         NA             NA  
 7  1994     7          55.6   33.3           292.          188.      291.        NA             51.4
 8  1994     8          28      0              60.8          68.1      57.6       NA             16.1
 9  1994     9          NA     NA              NA            NA        NA         NA             NA  
10  1994    10          20      0               8.8           9.3       3.6       NA              0  
# … with 286 more rows, and 244 more variables

2b)这是获取每个站点和月份的总和的替代解决方案。这更容易用于进一步的步骤(尤其是 ggplot2 中的可视化)。我也觉得,代码更直接!

rainfall_long_df %>%
    group_by(`Município/Posto`, Ano, Mês) %>%
    summarise(rainfall_per_month = sum(value))

结果将是每月和站点降雨量总和的长版本。

# A tibble: 62,319 x 4
# Groups:   Município/Posto, Ano [5,522]
   `Município/Posto`   Ano   Mês rainfall_per_month
   <chr>             <dbl> <dbl>              <dbl>
 1 Agua Branca        1994     1              174. 
 2 Agua Branca        1994     2               NA  
 3 Agua Branca        1994     3              285. 
 4 Agua Branca        1994     4               NA  
 5 Agua Branca        1994     5              176. 
 6 Agua Branca        1994     6               NA  
 7 Agua Branca        1994     7               55.6
 8 Agua Branca        1994     8               28  
 9 Agua Branca        1994     9               NA  
10 Agua Branca        1994    10               20  
# … with 62,309 more rows
于 2020-01-24T17:50:04.153 回答
0

首先,我要感谢您的回复。其次,对于结构不正确的问题(我第一次来这里),我深表歉意,我也是 R 世界的新手。我将这些数据用作水文学研究的一部分,并且这种结构对于使用HydroTSM 包和后来的 SWAT。

我做了推荐的测试,但出现了一些问题。并且都参加了我的问题的解决。但是,我意识到在创建日期时,闰年有一个小问题,但是我手动删除了这些日期。

在构建数据库时如何考虑闰年?

谢谢你。

于 2020-01-24T22:32:45.650 回答