Stack Overflow em Português Asked on September 26, 2021
bom dia.
É minha primeira postagem aqui. Acabo de iniciar minha jornada no “R” e estou com uma dificuldade com datas. Eu até que consegui chegar ao resultado que eu queria, no entanto, dei uma volta, no meu entender, MUITO grande. Acredito que haja uma forma mais simples de fazer o que eu fiz.
A questão é: alguém conhece uma forma mais simples de nomear os meses no caso de um dataset desorganizado importado de um arquivo “.csv”?
Não sei se fui claro na minha pergunta, por isso vou colocar meu percurso:
Importei os dados e gravei no objeto "fen" usando:
fen<-read.csv("Noronha.csv", sep=";")
No entanto, como não sei carregar o arquivo aqui, vou colocar os vetores para que seja possível reproduzir o data frame tal como obtive:
Ano<-c(2012:2020)
Janeiro<-c(112,127,121,131,150,158,137,165,164)
Fevereiro<-c(101,101,94,114,126,119,122,138,144)
Marco<-c(97,101,101,123,126,138,137,154,114)
Abril<-c(97,94,97,122,125,141,129,142,6)
Maio<-c(96,98,98,136,126,135,136,144,4)
Gravo o dataframe com o nome de “fen”:
fen<-data.frame(Ano, Janeiro, Fevereiro, Marco, Abril, Maio)
O resultado (o mesmo da importação do .csv) vai ser este:
Ano Janeiro Fevereiro Marco Abril Maio
1 2012 112 101 97 97 96
2 2013 127 101 101 94 98
3 2014 121 94 101 97 98
4 2015 131 114 123 122 136
5 2016 150 126 126 125 126
6 2017 158 119 138 141 135
7 2018 137 122 137 129 136
8 2019 165 138 154 142 144
9 2020 164 144 114 6 4
Daí começa minha saga:
Carrego os pacotes:
library(dplyr)
library(tidyr)
library(lubridate)
Em seguida, uso a função “gather” para organizar o dataframe e gravo no mesmo objeto “fen”:
fen<-gather(fen, Mes, Voos, c("Janeiro":"Maio"))
Resultado:
Ano Mes Voos
1 2012 Janeiro 112
2 2013 Janeiro 127
3 2014 Janeiro 121
4 2015 Janeiro 131
5 2016 Janeiro 150
6 2017 Janeiro 158
7 2018 Janeiro 137
8 2019 Janeiro 165
9 2020 Janeiro 164
10 2012 Fevereiro 101
11 2013 Fevereiro 101
12 2014 Fevereiro 94
13 2015 Fevereiro 114
14 2016 Fevereiro 126
15 2017 Fevereiro 119
16 2018 Fevereiro 122
17 2019 Fevereiro 138
18 2020 Fevereiro 144
19 2012 Março 97
20 2013 Março 101
21 2014 Março 101
22 2015 Março 123
23 2016 Março 126
24 2017 Março 138
25 2018 Março 137
26 2019 Março 154
27 2020 Março 114
28 2012 Abril 97
29 2013 Abril 94
30 2014 Abril 97
31 2015 Abril 122
32 2016 Abril 125
33 2017 Abril 141
34 2018 Abril 129
35 2019 Abril 142
36 2020 Abril 6
37 2012 Maio 96
38 2013 Maio 98
39 2014 Maio 98
40 2015 Maio 136
41 2016 Maio 126
42 2017 Maio 135
43 2018 Maio 136
44 2019 Maio 144
45 2020 Maio 4
Depois, para pode converter no formato data, preciso criar os dias.
Daí crio um vetor com o dia “1” para cada uma das linhas:
dia<-c(rep("1", 45))
E, depois, uso o “cbind” para juntar ao data frame principal. Gravo com o mesmo nome “fen”:
fen<-cbind(fen, dia)
Depois, uso a função “unite” para juntar ano, mês e dia, em uma coluna chamada “dt”:
fen<-fen%>%
unite(Ano, Mes, dia, col=dt, sep = "-")
Checo a qual classe pertence esse coluna “dt”.
Constato que é do tipo “chr”
str(fen)
'data.frame': 45 obs. of 2 variables:
$ dt : chr "2012-Janeiro-1" "2013-Janeiro-1" "2014-Janeiro-1" "2015-Janeiro-1" ...
$ Voos: int 112 127 121 131 150 158 137 165 164 101 ...
Em seguida, uso a função “as.POSIXct” para gravar a recém-criada coluna “dt” no formato “date”
fen$dt<-as.POSIXct(fen$dt, format="%Y-%B-%d")
E confiro a classe:
'data.frame': 45 obs. of 2 variables:
$ dt : POSIXct, format: "2012-01-01" "2013-01-01" "2014-01-01" "2015-01-01" ...
$ Voos: int 112 127 121 131 150 158 137 165 164 101 ...
Rodei o Cheat sheet do lubridate e não consegui transformar esse o formato “2012-01-01” em “2012-Jan-01”. Então, criei uma nova coluna chamada “mes_abbr”, usando a função “month” do lubridate.
mes_abbr<-month(fen$dt, label = T, abbr = T)
Depois, adicionei-a ao dataframe usando o “cbind”. Criei um novo dataframe (“fen2”)
fen2<-cbind(fen, mes_abbr)
Finalmente, criei um outro dataframe (“fen3”): 1) separando a coluna “dt”, 2) escolhendo as colunas que me interessavam (ano, mês abreviado e voos) e 3) ordenando por ano e mês:
fen3<-fen2%>%
separate(dt, into=c("ano", "mes", "dia"))%>%
select(ano, mes_abbr, Voos)%>%
arrange(ano, mes)
O resultado:
ano mes_abbr Voos
1 2012 jan 112
2 2012 fev 101
3 2012 mar 97
4 2012 abr 97
5 2012 mai 96
6 2013 jan 127
7 2013 fev 101
8 2013 mar 101
9 2013 abr 94
10 2013 mai 98
11 2014 jan 121
12 2014 fev 94
13 2014 mar 101
14 2014 abr 97
15 2014 mai 98
16 2015 jan 131
17 2015 fev 114
18 2015 mar 123
19 2015 abr 122
20 2015 mai 136
21 2016 jan 150
22 2016 fev 126
23 2016 mar 126
24 2016 abr 125
25 2016 mai 126
26 2017 jan 158
27 2017 fev 119
28 2017 mar 138
29 2017 abr 141
30 2017 mai 135
31 2018 jan 137
32 2018 fev 122
33 2018 mar 137
34 2018 abr 129
35 2018 mai 136
36 2019 jan 165
37 2019 fev 138
38 2019 mar 154
39 2019 abr 142
40 2019 mai 144
41 2020 jan 164
42 2020 fev 144
43 2020 mar 114
44 2020 abr 6
45 2020 mai 4
Pronto, assim consegui colocar no formato que eu queria e alcancei meu objetivo: fazer um gráfico que viesse no eixo “X” o mês abreviado.
No entanto, algo me diz que há um jeito bem mais simples de chegar a esse resultado. Se alguém puder me ajudar com isso, agradeço.
Obrigado pelas dicas Rui Barradas. Continuei pesquisando e testando e encontrei essa outra possibilidade:
Criei um novo objeto "fen3".
Usei a funcao "paste0" para colar na coluna "dt" o "Ano", o "Mes" e acrescento uma coluna só com "01" (para os dias). Concatenei (%>%) com...
...a função "ymd()" do lubridate para converter no formato "yyyy-mm-dd" e, ao mesmo tempo...
criei a coluna "ano" e atribui o os atributos da parte "year" da coluna "dt" recem-criada
fiz o mesmo para a coluna "mes", mas ai, o pulo do gato foi a conversao do mes na forma abreviada usando os recursos da funcao "month" do lubridate
criei a coluna "dia"
selecionei a coluna "ano", "mes", "n_voos"
organizei por "ano" e "mes".
E ai ficou organizado porque agora ele esta reconhendo essa coluna como "date" e nao como "character"
fen3<-fen2%>%
mutate(dt=paste0(Ano, Mes, "01")%>%
ymd(),
ano=year(dt),
mes=month(dt, abbr=T, label = T),
dia=day(dt))%>%
select(ano, mes, n_voos)%>%
arrange(ano, mes)
Resultado:
ano mes n_voos
1 2012 jan 112
2 2012 fev 101
3 2012 mar 97
4 2012 abr 97
5 2012 mai 96
6 2013 jan 127
7 2013 fev 101
8 2013 mar 101
9 2013 abr 94
10 2013 mai 98
11 2014 jan 121
12 2014 fev 94
13 2014 mar 101
14 2014 abr 97
15 2014 mai 98
16 2015 jan 131
17 2015 fev 114
18 2015 mar 123
19 2015 abr 122
20 2015 mai 136
21 2016 jan 150
22 2016 fev 126
23 2016 mar 126
24 2016 abr 125
25 2016 mai 126
26 2017 jan 158
27 2017 fev 119
28 2017 mar 138
29 2017 abr 141
30 2017 mai 135
31 2018 jan 137
32 2018 fev 122
33 2018 mar 137
34 2018 abr 129
35 2018 mai 136
36 2019 jan 165
37 2019 fev 138
38 2019 mar 154
39 2019 abr 142
40 2019 mai 144
41 2020 jan 164
42 2020 fev 144
43 2020 mar 114
44 2020 abr 6
45 2020 mai 4
Depois, plotei o grafico: agrupando as variaveis por ano...
...atribuindo mes no eixo "X", "n_voos" no eixo "Y" e alterei as cores usando a funcao "color" e atribuindo o "as.factor()" por ano.
ggplot(aes(group=ano))+
geom_line(aes(mes, n_voos, color= as.factor(ano)))
So nao consegui alterar o titulo da legenda no grafico. Ficou como "color= as.factor(ano)".
Answered by itamar on September 26, 2021
Se só precisa do mês abreviado, basta ficar com as 3 primeiras letras dessa coluna. Isso faz-se com a função R base substr
.
library(dplyr)
library(tidyr)
fen <- fen %>%
gather(Mes, Voos, c("Janeiro":"Maio")) %>%
mutate(mes_abbr = substr(Mes, 1, 3)) %>%
select(Ano, mes_abbr, Voos)
head(fen)
# Ano mes_abbr Voos
#1 2012 Jan 112
#2 2013 Jan 127
#3 2014 Jan 121
#4 2015 Jan 131
#5 2016 Jan 150
#6 2017 Jan 158
Para fazer um gráfico ggplot
a partir dos dados originais, não é necessário criar duas bases adicionais, pode-se fazer tudo com pipe.
Vou ainda usar o pacote zoo
, função as.yearmon
.
library(ggplot2)
fen %>%
gather(Mes, Voos, c("Janeiro":"Maio")) %>%
mutate(Mes = tolower(Mes),
Data = paste(Ano, Mes, 1, sep = "-"),
Data = as.Date(Data, "%Y-%B-%d"),
Data = zoo::as.yearmon(Data)) %>%
ggplot(aes(Data, Voos)) +
geom_point() +
geom_line()
Answered by Rui Barradas on September 26, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP