首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >数据组织沉淀

数据组织沉淀
EN

Stack Overflow用户
提问于 2020-01-25 00:34:41
回答 3查看 74关注 0票数 1

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

代码语言:javascript
复制
Season; YEAR; MONTH; DAY 01; DAY 02; DAY 03 ..... DAY 31 

data here

一开始,我想计算每个月的累积(我使用了精确度),但只计算了一个季节。现在我想做同样的事情,但要分离每个工作站,除了更改数据库的结构之外,我还将获得每个工作站的每日和每月值。其中第一列是日期,其他列是每个季节。

代码语言:javascript
复制
Date; season1; station2; estacao3 ....... estacaoN

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

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-01-25 01:50:04

此任务需要对数据集进行一些整形,首先将其变长,然后再将其变宽。DC37的答案已经描述了如何使用data.table来做到这一点。我推荐一种稍微不同的方法,只使用tidyverse函数。

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

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

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

代码语言:javascript
复制
  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看起来像这样:

代码语言:javascript
复制
 # 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)这就是您所要求的:从广泛的数据集中计算每月和站点的总和。

代码语言:javascript
复制
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)

这将导致:

代码语言:javascript
复制
# 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中的可视化)。我也觉得,代码更直接了!

代码语言:javascript
复制
rainfall_long_df %>%
    group_by(`Município/Posto`, Ano, Mês) %>%
    summarise(rainfall_per_month = sum(value))

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

代码语言:javascript
复制
# 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
票数 0
EN

Stack Overflow用户

发布于 2020-01-25 01:05:17

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

代码语言:javascript
复制
library(data.table)
df <- fread("../Dados_precipitacao.csv", skip = 2, header = TRUE)

然后,您可以使用data.table中的melt函数以long格式整形数据帧

代码语言:javascript
复制
library(data.table)
colonne <- grep("dia",colnames(df),value = TRUE)
dt.m <- melt(df, measure = list(colonne),value.name = "DIA")

现在,您有六列:

代码语言:javascript
复制
   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“),然后,我们将使用lubridate包中的ymd函数将此字符串转换为数据格式:

代码语言:javascript
复制
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

现在,我们可以使用data.table中的函数dcast以更宽的格式透视数据表,并为每个站点创建一列(这里我使用了Municipio/Posto):

代码语言:javascript
复制
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

希望这就是你正在寻找的东西。

顺便说一句:如果你发布一个可复制的数据示例,而不是插入一个指向整个数据集的链接(这是相当繁重的),这将使每个人的事情变得更容易。要知道如何做一个好的可重现的例子:How to make a great R reproducible example

票数 1
EN

Stack Overflow用户

发布于 2020-01-25 06:32:46

首先,我想感谢您的回复。其次,我很抱歉这个问题没有在正确的结构中(我第一次在这里),我对R的宇宙也是新的。我正在使用这些数据作为水文学研究的一部分,这个结构对于使用HydroTSM软件包和后来的特种部队是必要的。

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

在建立数据库时,您应该如何考虑闰年?

谢谢。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59900449

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档