数据组织沉淀
Data organization precipitation
我有一个降水数据库,其结构如下。
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
首先,由于您的数据框非常重(我只 运行 它的一部分代码),您可以使用 data.table
中的 fread
函数打开它(我转换您在 csv 文件中的 xlsx 文件)。
library(data.table)
df <- fread("../Dados_precipitacao.csv", skip = 2, header = TRUE)
然后,您可以使用 data.table
:
中的 melt
函数以 long
格式重塑数据框
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 "),然后,我们将使用lubridate
包中的 ymd
函数将此字符串转换为数据格式:
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):
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
希望这就是您要找的。
顺便说一句:如果您 post 一个可重现的数据示例而不是将 link 插入到完整数据集(这非常繁重),这将使每个人的事情变得更容易。要知道如何做一个好的可重现的例子:How to make a great R reproducible example
此任务需要对数据集进行一些重塑,首先使其变长然后再变宽。 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
首先感谢您的回复。
其次,对于结构不正确的问题(我第一次来这里),我深表歉意,我也是 R 世界的新手。
我将此数据用作水文学研究的一部分,此结构对于使用 HydroTSM 包以及以后的 SWAT 是必需的。
我做了推荐的测试,但出现了一些问题。
并且都参与了我的问题的解决。但是,我意识到创建日期时,闰年有一个小问题,但是我手动删除了这些日期。
建库时如何考虑闰年?
谢谢。
我有一个降水数据库,其结构如下。
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
首先,由于您的数据框非常重(我只 运行 它的一部分代码),您可以使用 data.table
中的 fread
函数打开它(我转换您在 csv 文件中的 xlsx 文件)。
library(data.table)
df <- fread("../Dados_precipitacao.csv", skip = 2, header = TRUE)
然后,您可以使用 data.table
:
melt
函数以 long
格式重塑数据框
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 "),然后,我们将使用lubridate
包中的 ymd
函数将此字符串转换为数据格式:
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):
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
希望这就是您要找的。
顺便说一句:如果您 post 一个可重现的数据示例而不是将 link 插入到完整数据集(这非常繁重),这将使每个人的事情变得更容易。要知道如何做一个好的可重现的例子:How to make a great R reproducible example
此任务需要对数据集进行一些重塑,首先使其变长然后再变宽。 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
首先感谢您的回复。 其次,对于结构不正确的问题(我第一次来这里),我深表歉意,我也是 R 世界的新手。 我将此数据用作水文学研究的一部分,此结构对于使用 HydroTSM 包以及以后的 SWAT 是必需的。
我做了推荐的测试,但出现了一些问题。 并且都参与了我的问题的解决。但是,我意识到创建日期时,闰年有一个小问题,但是我手动删除了这些日期。
建库时如何考虑闰年?
谢谢。