Данные организации осадков - PullRequest
1 голос
/ 24 января 2020

У меня есть база данных осадков, где она структурирована следующим образом.

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

данные здесь

Сначала я хотел рассчитать накопленные за каждый месяц (Я сделал это с помощью precintcon), но только на один сезон. Теперь я хочу сделать то же самое, но разделить каждую станцию, где у меня будут ежедневные и месячные значения для каждой станции, в дополнение к изменению структуры базы данных. Где первый столбец будет дата, а другие столбцы будут каждый сезон.

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

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

Ответы [ 3 ]

1 голос
/ 24 января 2020

Во-первых, поскольку ваш фрейм данных довольно тяжелый (я запускаю код только на его части), вы можете открыть его с помощью функции 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» из строки), затем мы будем использовать * Функция 1016 * из пакета 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

Теперь мы можем использовать функцию dcast из data.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

0 голосов
/ 25 января 2020

Во-первых, я хотел бы поблагодарить вас за ваши ответы. Во-вторых, я прошу прощения за вопрос, который не в правильной структуре (мой первый раз здесь), я также новичок во вселенной R. Я использую эти данные как часть гидрологического исследования, и эта структура необходима, чтобы использовать Пакет HydroTSM и позже SWAT.

Я сделал рекомендуемые тесты, но возникли некоторые вопросы. и оба занялись решением моей проблемы. Но я понял, что при создании дат високосные годы имели небольшую проблему, однако я удалил эти даты вручную.

Как вы могли бы учитывать високосные годы при создании базы данных?

Спасибо.

0 голосов
/ 24 января 2020

Эта задача требует некоторого изменения формы набора данных, сначала сделайте его длиннее, а затем снова шире. Ответ 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))

rainfall_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
...