<- read.table(file = "dados.csv", sep = ";")
dados1 <- read.table(file = "caminho-para-o-arquivo/dados.csv", sep = ";") dados2
2 Manipulação de dados
Neste capítulo falaremos alguns princípios básicos sobre manipulação de dados. Iremos trabalhar em um cenário mais próximo da realidade possível, ou seja, iremos trabalhar em cima de uma base de dados real. O objetivo é manipular a base e torná-la pronta para ser usada nos capítulos seguintes. Será mostrado desde como importar a base até como criar novas variáveis que poderão ser utilizadas em análises. Não será possível cobrir todo o ramo de manipulação em um só capítulo, mas iremos trabalhar com o máximo de ferramentas possíveis. Pacotes ou funções que não forem utilizadas aqui, mas que são interessantes serão mencionados ao longo do capítulo junto a links que contenham explicações de como utilizá-las. Vale ressaltar que estamos em um cenário mais básico e introdutório. Vamos começar.
2.0.1 Importação de dados
Um dos caminhos mais simples para importar dados no R é utilizando a função read.table()
. Está função é simples pois ja vem instalada com o R, faz parte do pacote base utils
, e importa arquivos nos formatos cvs e txt.
A utilização do pacote é bem simples, não preciso carregá-lo na memória usando library()
.
Observe que na função temos os argumentos file
e sep
. O file
indica o nome do arquivo que será importado e sep
indica qual o símbolo separador de colunas, que neste caso é a virgula. Note também que usamos dois exemplos, o primeiro considera que o seu arquivo está no diretório de trabalho (quando criamos o projeto e colocamos os arquivos de dados na pasta criada pelo projeto), não sendo necessário especificar o caminho até do arquivo. O outro exemplo mostra como especificar o local do seu arquivo. A função possui mais argumentos que você pode explorar usando o help, mas no geral, esses dois são os mais utilizados.
2.0.1.1 Extensão .txt ou .csv
Caso esteja trabalhando com arquivos do tipo cvs ou txt o pacote readr
irá servir muito bem. As funções deste pacote são bem rapidas e algumas delas são focadas em tranformar arquivos simples em data.frame
. Aglumas funções do pacote são
read_cvs()
: para arquivos delimitados por vírgulas.read_cvs2()
: para arquivos delimitados por ponto e vírgula.read_tsv()
: para arquivos delimitados por tabulações.read_delim()
: para aquivos com qualquer delimitador.read_fwf()
: para arquivos compactos que devem ter a largura de cada coluna especificada.read_table()
: para arquivos de texto tabulas com colunas separas por espaço.
Caso esta seja a primeira vez que você ira utilizar este pacote, será necessário instalá-lo em seu computar. Você pode fazer isso utilizando a função install.packages("readr")
e é claro, antes de usar qualquer pacote que não faça parte do R base, você deve carregá-lo. Como exemplo, consideramos um arquivo chamado dados1 que queremos importar para o R.
library(readr)
<- read_csv(file = "caminho-para-o-arquivo/dados1.csv")
dados_csv <- read_delim(file = "caminho-para-o-arquivo/dados1.txt", delim = " ") dados_txt
Apesar dos argumentos deste pacote serem semelhantes aos da função read.table()
, devemos nos atentar a algumas diferenças. Aqui é o argumento delim
que indica qual o separador das colunas no arquivo texto.
Vale ressaltar que para cada função read_
, existe umas respectiva função write_
para exportar o arquivo no formato de interesse. Como exemplo, queremos salvar a base de dados mtcars na pasta do meu computador com o nome cars:
write_csv(x = mtcars, path = "cars.csv")
write_delim(x = mtcars, delim = " ", path = "cars.txt")
2.0.1.2 Arquivos em Excel
Arquivos em formato xlsx são muito utilizados, porém o R não possui uma função nativa para importar este tipo de arquivo. Existem diversos pacotes para importar dados neste e formato e os principais são redxl
, xlsx
, XLConnect
e tydixl
. Apesar destes pacotes terem objetivos semelhantes, cada um tem suas peculiaridades, então aconselhamos estudar cada um desses pacotes e assim decidir qual melhor atende às suas necessidades. Aqui vamos mostrar apenas o pacote readxl
, pois é um dos mais facéis e diretos de se utilizar. Este pacote serve para importar e ler planilhas do Excel nos formatos xlsx ou xls. A seguir estão listadas algumas funções para importação e leitura de dados:
read_excel()
: esta função detecta automaticamente a extensão do arquivo, e importa arquivos do tipo xsl e xlsx.read_xsl()
: importa arquivos no formato xsl.read_xlsx()
: importa arquivos no formato xlsx.
Novamente, é necessário à instalação e carregamento do pacote caso não o tenha em seu computador. Para exemplicar consideramos um arquivo chamado dados2 que queremos importar para o R.
library(readxl)
<- read_excel(path = "dados2.xls")
dados_excel1 <- read_excel(path = "dados2.xlsx") dados_excelx1
Por meio da função read_excel
conseguimos importar tanto um arquivo no formato xls quanto no formato xlsx.
Podemos também exportar um arquivo em excel (.xls e .xlsx) ao considerar a função write_xlsx
do pacote writexl
. Suponha que temos o interesse em salvar a base de dados dados
em excel na pasta do computador (exportar) com o nome de dados_correto
:
library(writexl)
write_xlsx(dados, "dados_correto.xlsx")
2.0.2 Análise de consistência e tratamento de dados
O tratamento dos dados toma muitas vezes a maior parte do tempo de uma análise estatística.
A análise de consistência consiste em realizar uma primeira análise dos dados com o intuito de encontrar inconsistências. São exemplos de inconsistências:
boas práticas para nome das variáveis.
como erros de digitação;
indivíduos imputados mais de uma vez na planilha de dados de maneira errada;
identificar casos missings e avaliar se a observação está ausente de maneira correta ou não;
identificar as categorias de variáveis qualitativas.
A partir daqui iremos trabalhar com a nossa base de dados de COVID-19 em gestantes e puérperas.
Importando os dados
Como já aprendemos a importar os dados, vamos direto ao ponto. Nos dados estão no forma rds que não foi mencionado anteriormente, mas o pacote readr
tem uma função para importar este tipo de arquivo.
<- readr::read_rds("dados/dados_covid[SUJO].rds")
dados ::kable(head(dados)) knitr
DT_NOTIFIC | DT_SIN_PRI | DT_NASC | DT_INTERNA | SEM_PRI | SG_UF | ID_MN_RESI | CO_MUN_RES | CS_ZONA | CS_RACA | CS_ESCOL_N | idade | CS_GESTANT | PUERPERA | FEBRE | TOSSE | GARGANTA | DISPNEIA | DESC_RESP | SATURACAO | DIARREIA | VOMITO | FADIGA | PERD_OLFT | PERD_PALA | DOR_ABD | CARDIOPATI | HEMATOLOGI | HEPATICA | ASMA | DIABETES | NEUROLOGIC | PNEUMOPATI | IMUNODEPRE | RENAL | OBESIDADE | VACINA_COV | DOSE_1_COV | DOSE_2_COV | FAB_COV_1 | FAB_COV_2 | DT_ENTUTI | DT_SAIDUTI | UTI | SUPORT_VEN | EVOLUCAO |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
15/05/2020 | 06/05/2020 | 03/06/2003 | 15/05/2020 | 19 | CE | MORRINHOS | 230890 | NA | 4 | NA | 16 | 2 | NA | 1 | 1 | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | NA | 2 | 2 | 1 | ||
18/05/2020 | 10/05/2020 | 07/07/1996 | 15/05/2020 | 20 | PR | CURITIBA | 410690 | 1 | 1 | 2 | 23 | 2 | 2 | 2 | 2 | 2 | 1 | 2 | 2 | 1 | 2 | NA | NA | NA | NA | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | NA | NA | NA | NA | NA | 2 | 3 | 1 | ||
30/04/2020 | 20/04/2020 | 26/03/1996 | 24/04/2020 | 17 | SP | SAO CAETANO DO SUL | 354880 | 1 | 9 | 9 | 24 | 9 | 1 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | NA | NA | NA | NA | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | NA | NA | NA | NA | NA | 2 | 3 | 1 | ||
11/05/2020 | 04/05/2020 | 02/06/1986 | 09/05/2020 | 19 | PA | MARABA | 150420 | 1 | 4 | 4 | 33 | 5 | 1 | 1 | 1 | 2 | 2 | 1 | 2 | 2 | 2 | NA | NA | NA | NA | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | NA | NA | NA | NA | NA | 2 | 2 | 1 | ||
01/07/2020 | 12/06/2020 | 11/12/1996 | 30/06/2020 | 24 | DF | SANTA MARIA | 530150 | 1 | 9 | NA | 23 | 5 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 1 | 2 | NA | 1 | NA | NA | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | NA | NA | NA | NA | NA | 2 | 3 | 1 | ||
09/06/2020 | 09/06/2020 | 09/12/1984 | 09/06/2020 | 24 | RO | PORTO VELHO | 110020 | 1 | 4 | 2 | 35 | 3 | 2 | 1 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | NA | NA | NA | NA | NA | 2 | 3 | 1 |
2.0.2.1 Tratamento da base de dados
Inicialmente, vamos verificar os nomes das variáveis na base de dados por meio da função names
. Note que os nomes estão, de certa forma, padronizados. Todos maíusculos (com exceção de “idade”), separados por “_”. Este ainda não é o cenário ideal para trabalharmos, mas poderia ser pior, contendo maiúsculas, espaços e acentos. Utilizar os dados com essas características não impossibilita as futuras análises, mas pode atrapalhar quando precisamos selecionar algumas dessas variáveis.
names(dados)
[1] "DT_NOTIFIC" "DT_SIN_PRI" "DT_NASC" "DT_INTERNA" "SEM_PRI"
[6] "SG_UF" "ID_MN_RESI" "CO_MUN_RES" "CS_ZONA" "CS_RACA"
[11] "CS_ESCOL_N" "idade" "CS_GESTANT" "PUERPERA" "FEBRE"
[16] "TOSSE" "GARGANTA" "DISPNEIA" "DESC_RESP" "SATURACAO"
[21] "DIARREIA" "VOMITO" "FADIGA" "PERD_OLFT" "PERD_PALA"
[26] "DOR_ABD" "CARDIOPATI" "HEMATOLOGI" "HEPATICA" "ASMA"
[31] "DIABETES" "NEUROLOGIC" "PNEUMOPATI" "IMUNODEPRE" "RENAL"
[36] "OBESIDADE" "VACINA_COV" "DOSE_1_COV" "DOSE_2_COV" "FAB_COV_1"
[41] "FAB_COV_2" "DT_ENTUTI" "DT_SAIDUTI" "UTI" "SUPORT_VEN"
[46] "EVOLUCAO"
uma boa prática consiste em padronizar os nomes das variáveis, até para facilitar a lembrança deles. Para isso, utilizaremos o pacote janitor
para a arrumação da base de dados. Usamos a função clean_names()
para primeiro ajuste dos nomes das variáveis.
<- janitor::clean_names(dados)
dados names(dados)
[1] "dt_notific" "dt_sin_pri" "dt_nasc" "dt_interna" "sem_pri"
[6] "sg_uf" "id_mn_resi" "co_mun_res" "cs_zona" "cs_raca"
[11] "cs_escol_n" "idade" "cs_gestant" "puerpera" "febre"
[16] "tosse" "garganta" "dispneia" "desc_resp" "saturacao"
[21] "diarreia" "vomito" "fadiga" "perd_olft" "perd_pala"
[26] "dor_abd" "cardiopati" "hematologi" "hepatica" "asma"
[31] "diabetes" "neurologic" "pneumopati" "imunodepre" "renal"
[36] "obesidade" "vacina_cov" "dose_1_cov" "dose_2_cov" "fab_cov_1"
[41] "fab_cov_2" "dt_entuti" "dt_saiduti" "uti" "suport_ven"
[46] "evolucao"
Veja que ele deixou todos os nomes minúsculos. Neste caso não foi feito, mas a função substitui o espaço por “_” e tira acentos. Isso ajuda a evitar problemas futuros em algumas análises que não lidam muito bem com acentos e espaços nos nomes das variáveis.
Outro problema comum é a presença de linhas e colunas vazias. Na base de dados em questão, não há linhas nem colunas em branco, como pode ser visto na saída abaixo.
::remove_empty(dados,"rows")
janitor::remove_empty(dados,"cols") janitor
2.0.2.2
Identificando casos duplicados
Outra boa prática é identificar casos duplicados, isto é, identificar se há casos erroneamente repetidos. O ideal é utilizar variável chave do seu banco de dados, ou seja, aquela em que cada observação é única. Por exemplo, em uma base de dados de funcionários de uma empresa, uma variável chave poderia ser o CPF. Uma variável chave também pode ser a combinação de variáveis, gerando assim observações únicas. Para identificar casos duplicados, usamos a função get_dupes
do pacote janitor
. Em nosso banco de dados não tempos uma varíavel chave, então não vamos especificá-la na função, assim a função irá procurar observações repetidas considerando todas as variáveis, ou seja, linhas repetidas.
::get_dupes(dados) janitor
No variable names specified - using all columns.
No duplicate combinations found of: dt_notific, dt_sin_pri, dt_nasc, dt_interna, sem_pri, sg_uf, id_mn_resi, co_mun_res, cs_zona, ... and 37 other variables
[1] dt_notific dt_sin_pri dt_nasc dt_interna sem_pri sg_uf
[7] id_mn_resi co_mun_res cs_zona cs_raca cs_escol_n idade
[13] cs_gestant puerpera febre tosse garganta dispneia
[19] desc_resp saturacao diarreia vomito fadiga perd_olft
[25] perd_pala dor_abd cardiopati hematologi hepatica asma
[31] diabetes neurologic pneumopati imunodepre renal obesidade
[37] vacina_cov dose_1_cov dose_2_cov fab_cov_1 fab_cov_2 dt_entuti
[43] dt_saiduti uti suport_ven evolucao dupe_count
<0 linhas> (ou row.names de comprimento 0)
Em nosso caso, não temos casos duplicados. Caso tivesse, seria necessário remover as linhas duplicadas. Isto pode ser feito com o uso da função distinct
do pacote dplyr
.
2.0.3 Identificar problemas nas variáveis da base de dados
Outra etapa importante na análise de consistência é identificar o tipo de variável e ver se o R está interpretando corretamente o tipo de cada variável.
Temos na nossa base de dados variáveis de data, além de variáveis qualitativas e quantitativas (veja o dicionário das variáveis na em: refenciar parte). Assim, precisamos entender se o R realmente entendeu todas as variáveis da maneira correta. Uma maneira de identificar isso e também de ver algumas descritivas das variáveis que nos auxiliam a ver possíveis inconsistências na base de dados é a a função glimpse
do pacote dplyr
. A função skim
do pacote skimr
também pode ajudar nisso.
library(dplyr)
Attaching package: 'dplyr'
The following objects are masked from 'package:stats':
filter, lag
The following objects are masked from 'package:base':
intersect, setdiff, setequal, union
glimpse(dados)
Rows: 11,523
Columns: 46
$ dt_notific <chr> "15/05/2020", "18/05/2020", "30/04/2020", "11/05/2020", "01…
$ dt_sin_pri <chr> "06/05/2020", "10/05/2020", "20/04/2020", "04/05/2020", "12…
$ dt_nasc <chr> "03/06/2003", "07/07/1996", "26/03/1996", "02/06/1986", "11…
$ dt_interna <chr> "15/05/2020", "15/05/2020", "24/04/2020", "09/05/2020", "30…
$ sem_pri <int> 19, 20, 17, 19, 24, 24, 26, 27, 28, 24, 14, 29, 28, 10, 36,…
$ sg_uf <chr> "CE", "PR", "SP", "PA", "DF", "RO", "PI", "RS", "PE", "MA",…
$ id_mn_resi <chr> "MORRINHOS", "CURITIBA", "SAO CAETANO DO SUL", "MARABA", "S…
$ co_mun_res <int> 230890, 410690, 354880, 150420, 530150, 110020, 221100, 431…
$ cs_zona <int> NA, 1, 1, 1, 1, 1, 1, 1, 1, 1, NA, 1, 1, 1, NA, 1, 1, NA, 2…
$ cs_raca <int> 4, 1, 9, 4, 9, 4, 9, 1, 4, 9, 4, 4, 4, 4, 4, 9, 4, 9, 4, 4,…
$ cs_escol_n <int> NA, 2, 9, 4, NA, 2, 4, 2, NA, NA, NA, 9, 9, 3, 3, NA, 3, NA…
$ idade <dbl> 16, 23, 24, 33, 23, 35, 31, 17, 22, 29, 28, 22, 27, 25, 26,…
$ cs_gestant <int> 2, 2, 9, 5, 5, 3, 1, 5, 3, 3, 4, 3, 5, 3, 3, 3, 3, 9, 3, 3,…
$ puerpera <int> NA, 2, 1, 1, 1, 2, NA, 1, NA, 1, NA, NA, 1, 2, 1, NA, NA, 1…
$ febre <int> 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, NA, 1, 1, 1, 1, 1, 1, 1, 1…
$ tosse <int> 1, 2, 2, 1, 2, 1, 1, 1, NA, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1…
$ garganta <int> NA, 2, 2, 2, 2, 2, 2, NA, 1, NA, 2, NA, 2, 1, 1, 2, 2, NA, …
$ dispneia <int> NA, 1, 2, 2, 2, 2, 2, 1, NA, NA, 1, NA, 2, 1, 2, 1, 1, NA, …
$ desc_resp <int> NA, 2, 2, 1, 2, 2, 1, 1, NA, 1, 1, NA, 2, 1, 2, 2, 1, NA, 1…
$ saturacao <int> NA, 2, 2, 2, 2, 2, 2, 1, NA, NA, 2, NA, 2, 2, 2, 1, 1, NA, …
$ diarreia <int> NA, 1, 2, 2, 1, 2, 2, 1, NA, NA, 2, NA, 2, 1, 2, 2, 2, NA, …
$ vomito <int> NA, 2, 2, 2, 2, 2, 2, 2, NA, NA, 2, NA, 2, 1, 2, 2, 2, NA, …
$ fadiga <int> NA, NA, NA, NA, NA, 2, NA, NA, NA, NA, 2, NA, NA, 2, 2, 2, …
$ perd_olft <int> NA, NA, NA, NA, 1, 2, NA, NA, NA, NA, 2, NA, NA, 1, 2, 1, 2…
$ perd_pala <int> NA, NA, NA, NA, NA, 2, NA, NA, NA, NA, 2, NA, NA, 1, 2, 2, …
$ dor_abd <int> NA, NA, NA, NA, NA, 2, NA, NA, NA, NA, 2, NA, NA, 2, 2, 2, …
$ cardiopati <int> NA, 2, 2, 2, 2, 2, NA, 2, NA, NA, NA, NA, 2, 2, 1, NA, NA, …
$ hematologi <int> NA, 2, 2, 2, 2, 2, NA, 2, NA, NA, NA, NA, 2, 2, 2, NA, NA, …
$ hepatica <int> NA, 2, 2, 2, 2, 2, NA, 2, NA, NA, NA, NA, 2, 2, 2, NA, NA, …
$ asma <int> NA, 2, 2, 2, 2, 2, NA, 2, NA, NA, NA, NA, 2, 2, 2, NA, NA, …
$ diabetes <int> NA, 2, 2, 2, 2, 2, NA, 2, NA, NA, NA, NA, 2, 2, 2, NA, NA, …
$ neurologic <int> NA, 2, 2, 2, 2, 2, NA, 2, NA, NA, NA, NA, 2, 2, 1, NA, NA, …
$ pneumopati <int> NA, 2, 2, 2, 2, 2, NA, 2, NA, NA, NA, NA, 2, 2, 2, NA, NA, …
$ imunodepre <int> NA, 2, 2, 2, 2, 2, NA, 2, NA, NA, NA, NA, 2, 2, 2, NA, NA, …
$ renal <int> NA, 2, 2, 2, 2, 2, NA, 2, NA, NA, NA, NA, 2, 2, 2, NA, NA, …
$ obesidade <int> NA, 2, 2, 2, 2, 2, NA, 2, NA, NA, NA, NA, 2, 2, 2, NA, NA, …
$ vacina_cov <int> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ dose_1_cov <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ dose_2_cov <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ fab_cov_1 <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ fab_cov_2 <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ dt_entuti <chr> "", "", "", "", "", "", "", "30/06/2020", "", "12/07/2020",…
$ dt_saiduti <chr> "", "", "", "", "", "", "", "29/07/2020", "", "", "", "", "…
$ uti <int> 2, 2, 2, 2, 2, 2, 2, 1, 2, 1, 2, 2, 2, 2, 2, 2, 1, 1, NA, 2…
$ suport_ven <int> 2, 3, 3, 2, 3, 3, 9, 1, 3, 3, 3, 3, 3, 2, 3, 2, 1, 2, 3, 2,…
$ evolucao <int> 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, NA, 1, 1, 1, 1, 1, 1…
No R, as variáveis qualititativas são nomeadas “factor”, as variáveis quantitativas são nomeadas “numeric” e as variáveis de data são “date”. Note que na importação dos dados o R não entendeu corretamente os tipos de variáveis. Mas vamos corrigir isso no que segue.
Começando pela data, vamos rodar o seguinte código:
$dt_notific <- as.Date(dados$dt_notific, format = "%d/%m/%Y")
dados$dt_sin_pri <- as.Date(dados$dt_sin_pri, format = "%d/%m/%Y")
dados$dt_nasc <- as.Date(dados$dt_nasc, format = "%d/%m/%Y")
dados$dt_interna <- as.Date(dados$dt_interna, format = "%d/%m/%Y")
dados$dt_entuti <- as.Date(dados$dt_entuti, format = "%d/%m/%Y")
dados$dt_saiduti <- as.Date(dados$dt_saiduti, format = "%d/%m/%Y") dados
A função as.Date
informa para o R que a variável indicada é de data. O argumento format
indica o formato que está a data, nesse caso, “dia/mês/ano”. Aqui é possível verificar todos os formatos de datas da função. Vamos ver como ficou:
glimpse(dados)
Rows: 11,523
Columns: 46
$ dt_notific <date> 2020-05-15, 2020-05-18, 2020-04-30, 2020-05-11, 2020-07-01…
$ dt_sin_pri <date> 2020-05-06, 2020-05-10, 2020-04-20, 2020-05-04, 2020-06-12…
$ dt_nasc <date> 2003-06-03, 1996-07-07, 1996-03-26, 1986-06-02, 1996-12-11…
$ dt_interna <date> 2020-05-15, 2020-05-15, 2020-04-24, 2020-05-09, 2020-06-30…
$ sem_pri <int> 19, 20, 17, 19, 24, 24, 26, 27, 28, 24, 14, 29, 28, 10, 36,…
$ sg_uf <chr> "CE", "PR", "SP", "PA", "DF", "RO", "PI", "RS", "PE", "MA",…
$ id_mn_resi <chr> "MORRINHOS", "CURITIBA", "SAO CAETANO DO SUL", "MARABA", "S…
$ co_mun_res <int> 230890, 410690, 354880, 150420, 530150, 110020, 221100, 431…
$ cs_zona <int> NA, 1, 1, 1, 1, 1, 1, 1, 1, 1, NA, 1, 1, 1, NA, 1, 1, NA, 2…
$ cs_raca <int> 4, 1, 9, 4, 9, 4, 9, 1, 4, 9, 4, 4, 4, 4, 4, 9, 4, 9, 4, 4,…
$ cs_escol_n <int> NA, 2, 9, 4, NA, 2, 4, 2, NA, NA, NA, 9, 9, 3, 3, NA, 3, NA…
$ idade <dbl> 16, 23, 24, 33, 23, 35, 31, 17, 22, 29, 28, 22, 27, 25, 26,…
$ cs_gestant <int> 2, 2, 9, 5, 5, 3, 1, 5, 3, 3, 4, 3, 5, 3, 3, 3, 3, 9, 3, 3,…
$ puerpera <int> NA, 2, 1, 1, 1, 2, NA, 1, NA, 1, NA, NA, 1, 2, 1, NA, NA, 1…
$ febre <int> 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, NA, 1, 1, 1, 1, 1, 1, 1, 1…
$ tosse <int> 1, 2, 2, 1, 2, 1, 1, 1, NA, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1…
$ garganta <int> NA, 2, 2, 2, 2, 2, 2, NA, 1, NA, 2, NA, 2, 1, 1, 2, 2, NA, …
$ dispneia <int> NA, 1, 2, 2, 2, 2, 2, 1, NA, NA, 1, NA, 2, 1, 2, 1, 1, NA, …
$ desc_resp <int> NA, 2, 2, 1, 2, 2, 1, 1, NA, 1, 1, NA, 2, 1, 2, 2, 1, NA, 1…
$ saturacao <int> NA, 2, 2, 2, 2, 2, 2, 1, NA, NA, 2, NA, 2, 2, 2, 1, 1, NA, …
$ diarreia <int> NA, 1, 2, 2, 1, 2, 2, 1, NA, NA, 2, NA, 2, 1, 2, 2, 2, NA, …
$ vomito <int> NA, 2, 2, 2, 2, 2, 2, 2, NA, NA, 2, NA, 2, 1, 2, 2, 2, NA, …
$ fadiga <int> NA, NA, NA, NA, NA, 2, NA, NA, NA, NA, 2, NA, NA, 2, 2, 2, …
$ perd_olft <int> NA, NA, NA, NA, 1, 2, NA, NA, NA, NA, 2, NA, NA, 1, 2, 1, 2…
$ perd_pala <int> NA, NA, NA, NA, NA, 2, NA, NA, NA, NA, 2, NA, NA, 1, 2, 2, …
$ dor_abd <int> NA, NA, NA, NA, NA, 2, NA, NA, NA, NA, 2, NA, NA, 2, 2, 2, …
$ cardiopati <int> NA, 2, 2, 2, 2, 2, NA, 2, NA, NA, NA, NA, 2, 2, 1, NA, NA, …
$ hematologi <int> NA, 2, 2, 2, 2, 2, NA, 2, NA, NA, NA, NA, 2, 2, 2, NA, NA, …
$ hepatica <int> NA, 2, 2, 2, 2, 2, NA, 2, NA, NA, NA, NA, 2, 2, 2, NA, NA, …
$ asma <int> NA, 2, 2, 2, 2, 2, NA, 2, NA, NA, NA, NA, 2, 2, 2, NA, NA, …
$ diabetes <int> NA, 2, 2, 2, 2, 2, NA, 2, NA, NA, NA, NA, 2, 2, 2, NA, NA, …
$ neurologic <int> NA, 2, 2, 2, 2, 2, NA, 2, NA, NA, NA, NA, 2, 2, 1, NA, NA, …
$ pneumopati <int> NA, 2, 2, 2, 2, 2, NA, 2, NA, NA, NA, NA, 2, 2, 2, NA, NA, …
$ imunodepre <int> NA, 2, 2, 2, 2, 2, NA, 2, NA, NA, NA, NA, 2, 2, 2, NA, NA, …
$ renal <int> NA, 2, 2, 2, 2, 2, NA, 2, NA, NA, NA, NA, 2, 2, 2, NA, NA, …
$ obesidade <int> NA, 2, 2, 2, 2, 2, NA, 2, NA, NA, NA, NA, 2, 2, 2, NA, NA, …
$ vacina_cov <int> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ dose_1_cov <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ dose_2_cov <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ fab_cov_1 <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ fab_cov_2 <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ dt_entuti <date> NA, NA, NA, NA, NA, NA, NA, 2020-06-30, NA, 2020-07-12, NA…
$ dt_saiduti <date> NA, NA, NA, NA, NA, NA, NA, 2020-07-29, NA, NA, NA, NA, NA…
$ uti <int> 2, 2, 2, 2, 2, 2, 2, 1, 2, 1, 2, 2, 2, 2, 2, 2, 1, 1, NA, 2…
$ suport_ven <int> 2, 3, 3, 2, 3, 3, 9, 1, 3, 3, 3, 3, 3, 2, 3, 2, 1, 2, 3, 2,…
$ evolucao <int> 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, NA, 1, 1, 1, 1, 1, 1…
Agora vamos lidar com as variáveis qualitativas. Veja que “cs_zona” foi identificada como int. Isso acontece porque ela foi tabulada como número, como posteriormente variáveis deste tipo serão recodificadas de acordo com o dicionário, precisamos tratá-la como fator. Já as demais variáveis qualitativas estão identificadas como numeric, dbl ou chacacter pois na tabulação suas categorias estão codificadas com números ou textos. Para então dizer ao R o verdadeiro tipo dessas variáveis, vamos utilizar os seguintes comandos:
$cs_raca <- as.factor(dados$cs_raca)
dados$cs_escol_n <- as.factor(dados$cs_escol_n)
dados$cs_gestant <- as.factor(dados$cs_gestant)
dados$puerpera <- as.factor(dados$puerpera)
dados$cs_zona <- as.factor(dados$cs_zona)
dados$febre <- as.factor(dados$febre)
dados$tosse <- as.factor(dados$tosse)
dados$suport_ven <- as.factor(dados$suport_ven)
dados$uti <- as.factor(dados$uti)
dados$evolucao <- as.factor(dados$evolucao) dados
Uma forma um pouco mais eficiente de fazer isso é selecionar as variáveis por meio de um vetor, por exemplo, quero que as variáveis da coluna 10 até a coluna 20 sejam fatores. Podemos fazer isso com a ajuda a função lapply
. Essa função, em resumo, nos possibilita aplicar uma função em uma lista de elementos e retorna uma lista de mesmo tamanho em que o resultado é a aplicação desta função a cada elemento da lista. Neste caso, aplicamos a função as.factor
nas colunas selecionadas (lista de elementos). Veja como é feito.
c(17:37)] <- lapply(dados[,c(17:37)], as.factor)
dados[,glimpse(dados)
Rows: 11,523
Columns: 46
$ dt_notific <date> 2020-05-15, 2020-05-18, 2020-04-30, 2020-05-11, 2020-07-01…
$ dt_sin_pri <date> 2020-05-06, 2020-05-10, 2020-04-20, 2020-05-04, 2020-06-12…
$ dt_nasc <date> 2003-06-03, 1996-07-07, 1996-03-26, 1986-06-02, 1996-12-11…
$ dt_interna <date> 2020-05-15, 2020-05-15, 2020-04-24, 2020-05-09, 2020-06-30…
$ sem_pri <int> 19, 20, 17, 19, 24, 24, 26, 27, 28, 24, 14, 29, 28, 10, 36,…
$ sg_uf <chr> "CE", "PR", "SP", "PA", "DF", "RO", "PI", "RS", "PE", "MA",…
$ id_mn_resi <chr> "MORRINHOS", "CURITIBA", "SAO CAETANO DO SUL", "MARABA", "S…
$ co_mun_res <int> 230890, 410690, 354880, 150420, 530150, 110020, 221100, 431…
$ cs_zona <fct> NA, 1, 1, 1, 1, 1, 1, 1, 1, 1, NA, 1, 1, 1, NA, 1, 1, NA, 2…
$ cs_raca <fct> 4, 1, 9, 4, 9, 4, 9, 1, 4, 9, 4, 4, 4, 4, 4, 9, 4, 9, 4, 4,…
$ cs_escol_n <fct> NA, 2, 9, 4, NA, 2, 4, 2, NA, NA, NA, 9, 9, 3, 3, NA, 3, NA…
$ idade <dbl> 16, 23, 24, 33, 23, 35, 31, 17, 22, 29, 28, 22, 27, 25, 26,…
$ cs_gestant <fct> 2, 2, 9, 5, 5, 3, 1, 5, 3, 3, 4, 3, 5, 3, 3, 3, 3, 9, 3, 3,…
$ puerpera <fct> NA, 2, 1, 1, 1, 2, NA, 1, NA, 1, NA, NA, 1, 2, 1, NA, NA, 1…
$ febre <fct> 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, NA, 1, 1, 1, 1, 1, 1, 1, 1…
$ tosse <fct> 1, 2, 2, 1, 2, 1, 1, 1, NA, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1…
$ garganta <fct> NA, 2, 2, 2, 2, 2, 2, NA, 1, NA, 2, NA, 2, 1, 1, 2, 2, NA, …
$ dispneia <fct> NA, 1, 2, 2, 2, 2, 2, 1, NA, NA, 1, NA, 2, 1, 2, 1, 1, NA, …
$ desc_resp <fct> NA, 2, 2, 1, 2, 2, 1, 1, NA, 1, 1, NA, 2, 1, 2, 2, 1, NA, 1…
$ saturacao <fct> NA, 2, 2, 2, 2, 2, 2, 1, NA, NA, 2, NA, 2, 2, 2, 1, 1, NA, …
$ diarreia <fct> NA, 1, 2, 2, 1, 2, 2, 1, NA, NA, 2, NA, 2, 1, 2, 2, 2, NA, …
$ vomito <fct> NA, 2, 2, 2, 2, 2, 2, 2, NA, NA, 2, NA, 2, 1, 2, 2, 2, NA, …
$ fadiga <fct> NA, NA, NA, NA, NA, 2, NA, NA, NA, NA, 2, NA, NA, 2, 2, 2, …
$ perd_olft <fct> NA, NA, NA, NA, 1, 2, NA, NA, NA, NA, 2, NA, NA, 1, 2, 1, 2…
$ perd_pala <fct> NA, NA, NA, NA, NA, 2, NA, NA, NA, NA, 2, NA, NA, 1, 2, 2, …
$ dor_abd <fct> NA, NA, NA, NA, NA, 2, NA, NA, NA, NA, 2, NA, NA, 2, 2, 2, …
$ cardiopati <fct> NA, 2, 2, 2, 2, 2, NA, 2, NA, NA, NA, NA, 2, 2, 1, NA, NA, …
$ hematologi <fct> NA, 2, 2, 2, 2, 2, NA, 2, NA, NA, NA, NA, 2, 2, 2, NA, NA, …
$ hepatica <fct> NA, 2, 2, 2, 2, 2, NA, 2, NA, NA, NA, NA, 2, 2, 2, NA, NA, …
$ asma <fct> NA, 2, 2, 2, 2, 2, NA, 2, NA, NA, NA, NA, 2, 2, 2, NA, NA, …
$ diabetes <fct> NA, 2, 2, 2, 2, 2, NA, 2, NA, NA, NA, NA, 2, 2, 2, NA, NA, …
$ neurologic <fct> NA, 2, 2, 2, 2, 2, NA, 2, NA, NA, NA, NA, 2, 2, 1, NA, NA, …
$ pneumopati <fct> NA, 2, 2, 2, 2, 2, NA, 2, NA, NA, NA, NA, 2, 2, 2, NA, NA, …
$ imunodepre <fct> NA, 2, 2, 2, 2, 2, NA, 2, NA, NA, NA, NA, 2, 2, 2, NA, NA, …
$ renal <fct> NA, 2, 2, 2, 2, 2, NA, 2, NA, NA, NA, NA, 2, 2, 2, NA, NA, …
$ obesidade <fct> NA, 2, 2, 2, 2, 2, NA, 2, NA, NA, NA, NA, 2, 2, 2, NA, NA, …
$ vacina_cov <fct> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ dose_1_cov <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ dose_2_cov <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ fab_cov_1 <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ fab_cov_2 <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ dt_entuti <date> NA, NA, NA, NA, NA, NA, NA, 2020-06-30, NA, 2020-07-12, NA…
$ dt_saiduti <date> NA, NA, NA, NA, NA, NA, NA, 2020-07-29, NA, NA, NA, NA, NA…
$ uti <fct> 2, 2, 2, 2, 2, 2, 2, 1, 2, 1, 2, 2, 2, 2, 2, 2, 1, 1, NA, 2…
$ suport_ven <fct> 2, 3, 3, 2, 3, 3, 9, 1, 3, 3, 3, 3, 3, 2, 3, 2, 1, 2, 3, 2,…
$ evolucao <fct> 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, NA, 1, 1, 1, 1, 1, 1…
Ótimo! Corrigimos as inconsistências das variáveis qualitativas. Mas outra questão surge: como faço para usar um rótulo nos números codificados nas categorias das variáveis qualitativas? Para o grupo, por exemplo, ao invés de aparecer 1 quero que apareça “sim”. Para isso, vamos utilizar o pacote forcats
que lida com variáveis qualitativas (categóricas). Para renomear as categorias das variáveis, vamos usar a função fct_recode
desse pacote:
$cs_raca <- forcats::fct_recode(dados$cs_raca,
dadosbranca = "1",
preta = "2",
amarela = "3",
parda = "4",
indigena = "5",
ignorado = "9")
$cs_escol_n <- forcats::fct_recode(dados$cs_escol_n,
dados"sem escola" = "0",
fund1 = "1",
fund2 = "2",
medio = "3",
superior = "4",
ignorado = "9")
$cs_gestant <- forcats::fct_recode(dados$cs_gestant,
dados"1tri" = "1",
"2tri" = "2",
"3tri" = "3",
IG_ig = "4",
nao = "5",
ignorado = "9")
$puerpera <- forcats::fct_recode(dados$puerpera,
dadossim = "1",
nao = "2",
ignorado = "9")
$cs_zona <- forcats::fct_recode(dados$cs_zona,
dadosurbana = "1",
rural = "2",
periurbana = "3",
ignorado = "9")
$febre <- forcats::fct_recode(dados$febre,
dadossim = "1",
nao = "2",
ignorado = "9")
$suport_ven <-forcats::fct_recode(dados$suport_ven,
dados"sim, invasivo" = "1",
"sim, nao invasivo" = "2",
nao = "3",
ignorado = "9")
$uti <-forcats::fct_recode(dados$uti,
dadossim = "1",
nao = "2",
ignorado = "9")
$evolucao <-forcats::fct_recode(dados$evolucao,
dadoscura = "1",
obito = "2",
"obito por outras causas" = "3",
ignorado = "9")
Este tramanto foi feito para todas as variáveis qualitativas da base, mas por conta do tamanho do código, omitimos algumas da saída.
Finalmente chegamos nas variáveis quantitativas. Uma forma de identificar problemas em variáveis quantitativas é avaliar os valores mínimo e máximo de cada variável e ver se tem algum valor impossível para a mesma. Em nosso caso podemos verificar a variável idade. Seria meio estranho encontrar alguém com valores extremamente altos ou negativos, concorda?! A função summary
pode ser uma opção boa aqui, ela nos formece algumas medidas descritivas como, media, mínimo, máximo, entre outros.
summary(dados$idade)
Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
10.00 25.00 30.00 30.25 35.00 55.00 9
Aparentemente nossa variável esta dentro do esperado, sem valores inesperados.
2.0.3.1 Transformação de dados
É possível modificar ou criar novas variáveis na base de dados por meio da função mutate
do pacote dplyr
, você pode veificar melhor essa função clicando aqui. Também podemos criar categorias com base em alguma condição por meio da função case_when
também do pacote dplyr
, veja melhor aqui. Para ficar mais claro, vamos a um exemplo combinando as duas funções. Vamos criar a variável “faixa_et”, onde as observações serão as faixas etárias. São essas: “<20”, “20-34” e “>=”. Veja como faz:
<- dados |>
dados mutate(faixa_et = case_when(
< 20 ~ "<20",
idade >= 20 & idade < 34 ~ "20-34",
idade >= 34 ~ ">=34"
idade
))
table(dados$faixa_et)#table nos mostra as observações da quela variável e a sua frequência.
<20 >=34 20-34
714 3862 6938
Aqui fizemos a utilização da função “pipe” |>
que agora está no pacote base do R, mas que antes era necessário carregá-la por meio de pacotes. Essa função é de extrema importância, facilita a programção no R de uma forma inimaginável. É válido dedicar um pouco de seu tempo para entender melhor essa função. Separamos alguns links que pode te ajudar a entender melhor e você pode acessá-los clickando aqui, aqui ou aqui. Como foi mencionado acima, a função foi adicionada ao R base há pouco tempo, então esses links se referem ao pipe “antigo”, mas fique tranquilo, a função é a mesma. Para resumir, o pipe pega a saída de uma função e a passa para outra função como um argumento. Isso nos permite vincular uma sequência de etapas de análise.
2.0.3.2 Manipulação de datas
Algo interessante também é trabalhar com a varíavel de datas. Podemos calulcar a diferença entre duas datas no R de forma bem simples por meio da função difftime
do pacote base do R. Para exemplificar vamos criar a variável “dias_uti” que vai ser ser quantos dias a pessoa ficou internada na uti. Vamos fazer isso calculando a diferença entre a data de saída e a data de entrada na uti e queremos o resultado em dias.
$dias_uti <- difftime(dados$dt_saiduti, dados$dt_entuti, units = "days")
dadosglimpse(dados)
Rows: 11,523
Columns: 48
$ dt_notific <date> 2020-05-15, 2020-05-18, 2020-04-30, 2020-05-11, 2020-07-01…
$ dt_sin_pri <date> 2020-05-06, 2020-05-10, 2020-04-20, 2020-05-04, 2020-06-12…
$ dt_nasc <date> 2003-06-03, 1996-07-07, 1996-03-26, 1986-06-02, 1996-12-11…
$ dt_interna <date> 2020-05-15, 2020-05-15, 2020-04-24, 2020-05-09, 2020-06-30…
$ sem_pri <int> 19, 20, 17, 19, 24, 24, 26, 27, 28, 24, 14, 29, 28, 10, 36,…
$ sg_uf <chr> "CE", "PR", "SP", "PA", "DF", "RO", "PI", "RS", "PE", "MA",…
$ id_mn_resi <chr> "MORRINHOS", "CURITIBA", "SAO CAETANO DO SUL", "MARABA", "S…
$ co_mun_res <int> 230890, 410690, 354880, 150420, 530150, 110020, 221100, 431…
$ cs_zona <fct> NA, urbana, urbana, urbana, urbana, urbana, urbana, urbana,…
$ cs_raca <fct> parda, branca, ignorado, parda, ignorado, parda, ignorado, …
$ cs_escol_n <fct> NA, fund2, ignorado, superior, NA, fund2, superior, fund2, …
$ idade <dbl> 16, 23, 24, 33, 23, 35, 31, 17, 22, 29, 28, 22, 27, 25, 26,…
$ cs_gestant <fct> 2tri, 2tri, ignorado, nao, nao, 3tri, 1tri, nao, 3tri, 3tri…
$ puerpera <fct> NA, nao, sim, sim, sim, nao, NA, sim, NA, sim, NA, NA, sim,…
$ febre <fct> sim, nao, sim, sim, nao, sim, sim, sim, sim, sim, sim, NA, …
$ tosse <fct> sim, nao, nao, sim, nao, sim, sim, sim, NA, sim, sim, sim, …
$ garganta <fct> NA, nao, nao, nao, nao, nao, nao, NA, sim, NA, nao, NA, nao…
$ dispneia <fct> NA, sim, nao, nao, nao, nao, nao, sim, NA, NA, sim, NA, nao…
$ desc_resp <fct> NA, nao, nao, sim, nao, nao, sim, sim, NA, sim, sim, NA, na…
$ saturacao <fct> NA, nao, nao, nao, nao, nao, nao, sim, NA, NA, nao, NA, nao…
$ diarreia <fct> NA, sim, nao, nao, sim, nao, nao, sim, NA, NA, nao, NA, nao…
$ vomito <fct> NA, nao, nao, nao, nao, nao, nao, nao, NA, NA, nao, NA, nao…
$ fadiga <fct> NA, NA, NA, NA, NA, nao, NA, NA, NA, NA, nao, NA, NA, nao, …
$ perd_olft <fct> NA, NA, NA, NA, sim, nao, NA, NA, NA, NA, nao, NA, NA, sim,…
$ perd_pala <fct> NA, NA, NA, NA, NA, nao, NA, NA, NA, NA, nao, NA, NA, sim, …
$ dor_abd <fct> NA, NA, NA, NA, NA, nao, NA, NA, NA, NA, nao, NA, NA, nao, …
$ cardiopati <fct> NA, nao, nao, nao, nao, nao, NA, nao, NA, NA, NA, NA, nao, …
$ hematologi <fct> NA, nao, nao, nao, nao, nao, NA, nao, NA, NA, NA, NA, nao, …
$ hepatica <fct> NA, nao, nao, nao, nao, nao, NA, nao, NA, NA, NA, NA, nao, …
$ asma <fct> NA, nao, nao, nao, nao, nao, NA, nao, NA, NA, NA, NA, nao, …
$ diabetes <fct> NA, nao, nao, nao, nao, nao, NA, nao, NA, NA, NA, NA, nao, …
$ neurologic <fct> NA, nao, nao, nao, nao, nao, NA, nao, NA, NA, NA, NA, nao, …
$ pneumopati <fct> NA, nao, nao, nao, nao, nao, NA, nao, NA, NA, NA, NA, nao, …
$ imunodepre <fct> NA, nao, nao, nao, nao, nao, NA, nao, NA, NA, NA, NA, nao, …
$ renal <fct> NA, nao, nao, nao, nao, nao, NA, nao, NA, NA, NA, NA, nao, …
$ obesidade <fct> NA, nao, nao, nao, nao, nao, NA, nao, NA, NA, NA, NA, nao, …
$ vacina_cov <fct> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ dose_1_cov <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ dose_2_cov <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ fab_cov_1 <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ fab_cov_2 <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ dt_entuti <date> NA, NA, NA, NA, NA, NA, NA, 2020-06-30, NA, 2020-07-12, NA…
$ dt_saiduti <date> NA, NA, NA, NA, NA, NA, NA, 2020-07-29, NA, NA, NA, NA, NA…
$ uti <fct> nao, nao, nao, nao, nao, nao, nao, sim, nao, sim, nao, nao,…
$ suport_ven <fct> "sim, nao invasivo", "nao", "nao", "sim, nao invasivo", "na…
$ evolucao <fct> cura, cura, cura, cura, cura, cura, cura, obito, cura, cura…
$ faixa_et <chr> "<20", "20-34", "20-34", "20-34", "20-34", ">=34", "20-34",…
$ dias_uti <drtn> NA days, NA days, NA days, NA days, NA days, NA days, NA d…
Note que não utilizamos a função mutate
para criar está nova variável, utilizamos apenas o $
para representar a variável e atribuímos a função. Assim, o R já entende como uma variável.
2.0.3.3 Manipulação de dados
Já temos a nossa base de dados devidamente tratada para prosseguir com a análise descritiva, mas quando falamos de manipulação de dados, um leque de possibilidades aparece. Em diversos cenários precisamos filtrar observações, reordená-las, selecionar variáveis específicas, entre outras coisas. Não poderíamos deixar de mencionar o poderoso tidyverse
. O tidyverse
é um pacote que contém um coleção de outros pacotes que são utilizados para manipulação, exploração e visualização de dados e que compartilham uma filosofia de design bem parecida, por isso de forma combinada permitem que você consiga fazer inúmeros trabalhos. Os pacotes que fazem parte desse universo são: dplyr
, tidyr
, ggplot2
, forcats
, purrr
, stringr
, tibble
e readr
. Anteriormente já trabalhamos com alguns destes pacotes, mas agora é válido aprofundarmos um pouco mais em alguns deles. Aqui você irá acessar o site do tidyverse
onde podera navegar por cada pacote e aprender mais sobre suas utilidades e aqui você irá acessar um post escrito pelo Laboratório de Data Scinence - UFES (daslab) que contem diversos exemplos práticos de uso de todos os pacotes do universo tidyverse
. Neste capítulo iremos trabalhar com algumas funções específicas.
2.0.3.3.1 Pacote dplyr
O dplyr
é extremamente útil e nos ajuda a resolver os desafios mais comuns de manipulação de dados.
Suas principais funções são:
filter() - filtra linhas;
group_by() - agrupa pela(s) variável(is) no argumento. Função muito útil quando usada a funçaõ summurise.
summarise() - reduz vários valores a um único resumo.
select() - seleciona colunas;
arrange() - ordena a base;
mutate() - cria/modifica colunas.
Já utilizamos algumas funções do pacote, vamos falar sobre outras. Como já avançamos um pouco sobre a utilização de funções, vamos combinar algumas funções, o que geralmente é feito no dia a dia.
#criando um novo banco de dados selecionando 3 variáveis
<- dados |>
dados_tratamento select(sg_uf, cs_zona, idade)
glimpse(dados_tratamento)
Rows: 11,523
Columns: 3
$ sg_uf <chr> "CE", "PR", "SP", "PA", "DF", "RO", "PI", "RS", "PE", "MA", "M…
$ cs_zona <fct> NA, urbana, urbana, urbana, urbana, urbana, urbana, urbana, ur…
$ idade <dbl> 16, 23, 24, 33, 23, 35, 31, 17, 22, 29, 28, 22, 27, 25, 26, 20…
Aqui criamos a base “dados_tratamento” onde apenas selecionamos algumas colunas da base de dados inicial com a função select
.
<- dados_tratamento |>
dados_tratamento2 filter(cs_zona == "urbana") |>
group_by(sg_uf) |>
summarise(media = mean(idade, na.rm = TRUE)) |>
arrange(desc(media))
::kable(head(dados_tratamento2)) knitr
sg_uf | media |
---|---|
AP | 36.66667 |
BA | 31.04152 |
RR | 31.00000 |
SP | 30.94237 |
RJ | 30.93570 |
MG | 30.93257 |
Vamos entender o código acima. Primeiro acessamos a base “dados_tratamento” e com função filter
selecionamos apenas as observações “urbana”. Após isso utilizamos a função group_by
para agrupar nossas observações pela variável “sg_uf” e por últimos, combinamos com a função summarise
para criar a variável “media” que será a media da variável idade. Note que nesta função utilizamos o argumento na.rm - TRUE
. Este argumento serve para indicar para a função se ela deve ou não remover valores NA's
do cálculo, o default é FALSE
. Como não é possível calcular a média de valores ausentes e temos variáveis ausentes, foi necessário utilizar este argumento. Caso contrário, Estados com valores faltantes ficariam com NA
. Por último, utilizamos a função arrange
para ordernar os dados em em ordem descrente pela variavel media. Uma dica para tentar entender melhor o funcionamento das funções é tentar refazer o código utilizando uma função de cada vez e ir vendo como fica. Então, em poucas linhas de códigos conseguimos criar uma base com a idade média dos Estados considerando apenas zonas urbanas, legal né?
2.0.3.3.2 Pacote stringr
Um desafio muito grande na manipulação de dados é extrair informações de caracteres. Em resumo caracteres são letras, símbolos, sinais, números que representem algo escrito, etc.. Essa sequência de caracteres formam o que chamamos de string
. Diversas vezes encontramos variáveis com categorias não padronizadas, como, por exemplo, uma variável contendo “São Paulo”, “sao paulo” e “sp”. Apesar de representarem o mesmo estado, elas são diferentes. Nesse sentido, uma parte muito importante no tratamento de dados é “lapidar” esse conjunto de caracteres para que seja possível usá-los nas análises. Essa é a introdução do post do daslab onde é passado de uma maneira muito prática como trabalhar com strings utilizando o pacote stringr
, la você vai aprender também sobre expressões regulares, que com certeza serão úteis em vários momentos da sua carreira. Link do post. Como as variáveis de texto do nosso banco de dados já estão bem padronizadas não será necessário realizar nenhum tratamento, mas por ser um pacote de extrema importância e que não havia sido mencionado ainda, deixamos ele aqui para que você possa se aprofundar mais. Como em nossa base dados as variáveis de texto estão padrozinados, não será necessário realizar nenhum tratamento.
2.0.3.4 Manipulando o formato da base de dados
Em certos casos é necessário mudar o formato das bases de dados, fazer com que colunas se tornem linhas vice-versa. Vamos utilizar a base “dados_tratamento”. Veja que ela está no formato long, em que as avaliações do mesmo indivíduo (variável de identificação de indivíduo é “registro”) estão nas linhas. Queremos que as zonas fiquem nas colunas, com as três colunas (vamos tirar valores ignorados): urbana, rural e periurbana, ou seja, queremos o formato wide. Um pacote do R que pode nos auxiliar a transformar formato long em wide e vice-versa é o tidyr
. A função que usaremos é spread
, como segue:
library(tidyr)
<- dados_tratamento |>
dados_formato filter(!is.na(cs_zona) & cs_zona != "ignorado") |>
mutate(id = row_number())
::kable(head(dados_formato)) knitr
sg_uf | cs_zona | idade | id |
---|---|---|---|
PR | urbana | 23 | 1 |
SP | urbana | 24 | 2 |
PA | urbana | 33 | 3 |
DF | urbana | 23 | 4 |
RO | urbana | 35 | 5 |
PI | urbana | 31 | 6 |
Fizemos pequenas alterações na base de dados. Primeiro realizamos um filtro para retirarmos valores faltantes da variável “cs_zona”, pois essa passará a
<- dados_formato |>
dados_formato2 pivot_wider(names_from = cs_zona, values_from = idade)
::kable(head(dados_formato2)) knitr
sg_uf | id | urbana | rural | periurbana |
---|---|---|---|---|
PR | 1 | 23 | NA | NA |
SP | 2 | 24 | NA | NA |
PA | 3 | 33 | NA | NA |
DF | 4 | 23 | NA | NA |
RO | 5 | 35 | NA | NA |
PI | 6 | 31 | NA | NA |
<- dados_formato2 |>
dados_formato3 pivot_longer(cols = c("urbana", "rural", "periurbana"), names_to = "cs_zona", values_to = "idade")
::kable(head(dados_formato3)) knitr
sg_uf | id | cs_zona | idade |
---|---|---|---|
PR | 1 | urbana | 23 |
PR | 1 | rural | NA |
PR | 1 | periurbana | NA |
SP | 2 | urbana | 24 |
SP | 2 | rural | NA |
SP | 2 | periurbana | NA |
2.0.3.5 Combinando bases de dados
Quando estamos trabalhando com dados, nem sempre uma única base irá conter todas as informações que precisamos, na verdade, isso é mais comum do que se possa imaginar. Assim, saber juntar duas bases de dados é indispensável. Vamos começar então falando sobre chave primária. Em resumo, chave primária se refere a um ou mais campos, onde combinados (no caso de mais de uma chave primária), não se repete na mesma tabela. Em outras palavras, uma chave primária no meu banco dados seria uma variável onde as observações não se repetem ou a combinação de variáveis que tornam as observações únicas. Para exemplicar vamos pegar nossa base de dados e separar em duas, para que posteriormente possamos juntalas. Como em nossa base de dados não temos naturalmente nenhuma chave primária, vamos utilizar a função mutate(id = row_number())
para criarmos um identificar único para este exemplo. Após isso, vamos dividir a nossa base de dados em duas, mantendo em comum entre elas apenas a nossa chave primária, neste caso, a variável “id”
<- dados |>
dados mutate(id = row_number()) |>
select(id, everything())#selecionar variavel id e todas as outras
<- dados[, c(1:24)]
dados1
glimpse(dados1)
Rows: 11,523
Columns: 24
$ id <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, …
$ dt_notific <date> 2020-05-15, 2020-05-18, 2020-04-30, 2020-05-11, 2020-07-01…
$ dt_sin_pri <date> 2020-05-06, 2020-05-10, 2020-04-20, 2020-05-04, 2020-06-12…
$ dt_nasc <date> 2003-06-03, 1996-07-07, 1996-03-26, 1986-06-02, 1996-12-11…
$ dt_interna <date> 2020-05-15, 2020-05-15, 2020-04-24, 2020-05-09, 2020-06-30…
$ sem_pri <int> 19, 20, 17, 19, 24, 24, 26, 27, 28, 24, 14, 29, 28, 10, 36,…
$ sg_uf <chr> "CE", "PR", "SP", "PA", "DF", "RO", "PI", "RS", "PE", "MA",…
$ id_mn_resi <chr> "MORRINHOS", "CURITIBA", "SAO CAETANO DO SUL", "MARABA", "S…
$ co_mun_res <int> 230890, 410690, 354880, 150420, 530150, 110020, 221100, 431…
$ cs_zona <fct> NA, urbana, urbana, urbana, urbana, urbana, urbana, urbana,…
$ cs_raca <fct> parda, branca, ignorado, parda, ignorado, parda, ignorado, …
$ cs_escol_n <fct> NA, fund2, ignorado, superior, NA, fund2, superior, fund2, …
$ idade <dbl> 16, 23, 24, 33, 23, 35, 31, 17, 22, 29, 28, 22, 27, 25, 26,…
$ cs_gestant <fct> 2tri, 2tri, ignorado, nao, nao, 3tri, 1tri, nao, 3tri, 3tri…
$ puerpera <fct> NA, nao, sim, sim, sim, nao, NA, sim, NA, sim, NA, NA, sim,…
$ febre <fct> sim, nao, sim, sim, nao, sim, sim, sim, sim, sim, sim, NA, …
$ tosse <fct> sim, nao, nao, sim, nao, sim, sim, sim, NA, sim, sim, sim, …
$ garganta <fct> NA, nao, nao, nao, nao, nao, nao, NA, sim, NA, nao, NA, nao…
$ dispneia <fct> NA, sim, nao, nao, nao, nao, nao, sim, NA, NA, sim, NA, nao…
$ desc_resp <fct> NA, nao, nao, sim, nao, nao, sim, sim, NA, sim, sim, NA, na…
$ saturacao <fct> NA, nao, nao, nao, nao, nao, nao, sim, NA, NA, nao, NA, nao…
$ diarreia <fct> NA, sim, nao, nao, sim, nao, nao, sim, NA, NA, nao, NA, nao…
$ vomito <fct> NA, nao, nao, nao, nao, nao, nao, nao, NA, NA, nao, NA, nao…
$ fadiga <fct> NA, NA, NA, NA, NA, nao, NA, NA, NA, NA, nao, NA, NA, nao, …
<- dados[, c(1, 25:49)]
dados2
glimpse(dados2)
Rows: 11,523
Columns: 26
$ id <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, …
$ perd_olft <fct> NA, NA, NA, NA, sim, nao, NA, NA, NA, NA, nao, NA, NA, sim,…
$ perd_pala <fct> NA, NA, NA, NA, NA, nao, NA, NA, NA, NA, nao, NA, NA, sim, …
$ dor_abd <fct> NA, NA, NA, NA, NA, nao, NA, NA, NA, NA, nao, NA, NA, nao, …
$ cardiopati <fct> NA, nao, nao, nao, nao, nao, NA, nao, NA, NA, NA, NA, nao, …
$ hematologi <fct> NA, nao, nao, nao, nao, nao, NA, nao, NA, NA, NA, NA, nao, …
$ hepatica <fct> NA, nao, nao, nao, nao, nao, NA, nao, NA, NA, NA, NA, nao, …
$ asma <fct> NA, nao, nao, nao, nao, nao, NA, nao, NA, NA, NA, NA, nao, …
$ diabetes <fct> NA, nao, nao, nao, nao, nao, NA, nao, NA, NA, NA, NA, nao, …
$ neurologic <fct> NA, nao, nao, nao, nao, nao, NA, nao, NA, NA, NA, NA, nao, …
$ pneumopati <fct> NA, nao, nao, nao, nao, nao, NA, nao, NA, NA, NA, NA, nao, …
$ imunodepre <fct> NA, nao, nao, nao, nao, nao, NA, nao, NA, NA, NA, NA, nao, …
$ renal <fct> NA, nao, nao, nao, nao, nao, NA, nao, NA, NA, NA, NA, nao, …
$ obesidade <fct> NA, nao, nao, nao, nao, nao, NA, nao, NA, NA, NA, NA, nao, …
$ vacina_cov <fct> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ dose_1_cov <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ dose_2_cov <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ fab_cov_1 <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ fab_cov_2 <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ dt_entuti <date> NA, NA, NA, NA, NA, NA, NA, 2020-06-30, NA, 2020-07-12, NA…
$ dt_saiduti <date> NA, NA, NA, NA, NA, NA, NA, 2020-07-29, NA, NA, NA, NA, NA…
$ uti <fct> nao, nao, nao, nao, nao, nao, nao, sim, nao, sim, nao, nao,…
$ suport_ven <fct> "sim, nao invasivo", "nao", "nao", "sim, nao invasivo", "na…
$ evolucao <fct> cura, cura, cura, cura, cura, cura, cura, obito, cura, cura…
$ faixa_et <chr> "<20", "20-34", "20-34", "20-34", "20-34", ">=34", "20-34",…
$ dias_uti <drtn> NA days, NA days, NA days, NA days, NA days, NA days, NA d…
Em “dados1” selecionamos as colunas de 1 até a 24, onde a coluna 1 é a variável “id”. Em dados 2 selecionamos a coluna depois e as colunas de 25 até a 49. Agora temos dois banco de dados e precisamos juntá-los.
Há algumas funções de combinação de duas bases de dados no pacote dplyr
. Elas recebem três argumentos: a primeira base a ser declarada (x=)
, a segunda base a ser declarada (y=)
e a variável de identificação informada no argumento by=
. Aqui estão as funções mais úteis:
left_join()
- retorna todas as linhas da base de dados no argumentox
e todas as colunas das duas bases de dados. Linhas da base de dados dex
sem correspondentes emy
receberãoNA
na base de dados combinada.right_join()
- retorna todas as linhas da base de dados no argumentoy
e todas as colunas das duas bases de dados. Linhas da base de dados dey
sem correspondentes emx
receberãoNA
na base de dados combinada.full_join()
- retorna todas as linhas e todas as colunas dex
e dey
. As linhas sem correspondência entre as bases receberãoNA
na base de dados combinada.inner_join()
- filtra a base de dados no argumentox
apenas onde tem valores correspondentes na base de dados no argumentoy
e todas as colunas das duas bases de dados.semi_join()
- filtra a base de dados no argumentox
apenas onde tem valores correspondentes na base de dados no argumentoy
, mantendo apenas as colunas da base de dados dex
.anti_join()
- filtra a base de dados no argumentox
para incluir apenas valores que não possuem correspondências na base de dados no argumentoy
.
Assim sendo, no nosso exemplo, tanto as funções left_join()
, right_join()
, full_join()
e inner_join()
retornarão a mesma combinação, pois “dados1” e “dados2” possuem exatamente os mesmos indivíduos, ou seja, não há nenhuma linha que esteja em uma das bases de dados e que não está na outra. Este cenário foi um pouco mais simples, mas pense que no dia a dia você irá encontrar bases onde você precisará encontrar chaves primarias entre elas. Além disso, varios problemas podem vir acompanhados, por exemplo, imagine que para juntar duas bases você utilizará uma chave formada pela combinação de duas variáveis: UF e Município. Em uma base a sua UF está no formato de sigla e na outra está sendo representada pelo código da UF atribuido pelo IBGE. Já na variável de Município, Em uma base os dados estão todos padronizados, maiúsculos e sem acentuação, já na outra base está no formato “padrão” com a primeira letra maiúscula e acentuação. Veja que será necessário um bom tratamento de dados para pode juntar essas bases. Voltando para o nosso exemplo, vamos a prática.
<- full_join(dados1, dados2, by=c("id"))
dados_todos
glimpse(dados_todos)
Rows: 11,523
Columns: 49
$ id <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, …
$ dt_notific <date> 2020-05-15, 2020-05-18, 2020-04-30, 2020-05-11, 2020-07-01…
$ dt_sin_pri <date> 2020-05-06, 2020-05-10, 2020-04-20, 2020-05-04, 2020-06-12…
$ dt_nasc <date> 2003-06-03, 1996-07-07, 1996-03-26, 1986-06-02, 1996-12-11…
$ dt_interna <date> 2020-05-15, 2020-05-15, 2020-04-24, 2020-05-09, 2020-06-30…
$ sem_pri <int> 19, 20, 17, 19, 24, 24, 26, 27, 28, 24, 14, 29, 28, 10, 36,…
$ sg_uf <chr> "CE", "PR", "SP", "PA", "DF", "RO", "PI", "RS", "PE", "MA",…
$ id_mn_resi <chr> "MORRINHOS", "CURITIBA", "SAO CAETANO DO SUL", "MARABA", "S…
$ co_mun_res <int> 230890, 410690, 354880, 150420, 530150, 110020, 221100, 431…
$ cs_zona <fct> NA, urbana, urbana, urbana, urbana, urbana, urbana, urbana,…
$ cs_raca <fct> parda, branca, ignorado, parda, ignorado, parda, ignorado, …
$ cs_escol_n <fct> NA, fund2, ignorado, superior, NA, fund2, superior, fund2, …
$ idade <dbl> 16, 23, 24, 33, 23, 35, 31, 17, 22, 29, 28, 22, 27, 25, 26,…
$ cs_gestant <fct> 2tri, 2tri, ignorado, nao, nao, 3tri, 1tri, nao, 3tri, 3tri…
$ puerpera <fct> NA, nao, sim, sim, sim, nao, NA, sim, NA, sim, NA, NA, sim,…
$ febre <fct> sim, nao, sim, sim, nao, sim, sim, sim, sim, sim, sim, NA, …
$ tosse <fct> sim, nao, nao, sim, nao, sim, sim, sim, NA, sim, sim, sim, …
$ garganta <fct> NA, nao, nao, nao, nao, nao, nao, NA, sim, NA, nao, NA, nao…
$ dispneia <fct> NA, sim, nao, nao, nao, nao, nao, sim, NA, NA, sim, NA, nao…
$ desc_resp <fct> NA, nao, nao, sim, nao, nao, sim, sim, NA, sim, sim, NA, na…
$ saturacao <fct> NA, nao, nao, nao, nao, nao, nao, sim, NA, NA, nao, NA, nao…
$ diarreia <fct> NA, sim, nao, nao, sim, nao, nao, sim, NA, NA, nao, NA, nao…
$ vomito <fct> NA, nao, nao, nao, nao, nao, nao, nao, NA, NA, nao, NA, nao…
$ fadiga <fct> NA, NA, NA, NA, NA, nao, NA, NA, NA, NA, nao, NA, NA, nao, …
$ perd_olft <fct> NA, NA, NA, NA, sim, nao, NA, NA, NA, NA, nao, NA, NA, sim,…
$ perd_pala <fct> NA, NA, NA, NA, NA, nao, NA, NA, NA, NA, nao, NA, NA, sim, …
$ dor_abd <fct> NA, NA, NA, NA, NA, nao, NA, NA, NA, NA, nao, NA, NA, nao, …
$ cardiopati <fct> NA, nao, nao, nao, nao, nao, NA, nao, NA, NA, NA, NA, nao, …
$ hematologi <fct> NA, nao, nao, nao, nao, nao, NA, nao, NA, NA, NA, NA, nao, …
$ hepatica <fct> NA, nao, nao, nao, nao, nao, NA, nao, NA, NA, NA, NA, nao, …
$ asma <fct> NA, nao, nao, nao, nao, nao, NA, nao, NA, NA, NA, NA, nao, …
$ diabetes <fct> NA, nao, nao, nao, nao, nao, NA, nao, NA, NA, NA, NA, nao, …
$ neurologic <fct> NA, nao, nao, nao, nao, nao, NA, nao, NA, NA, NA, NA, nao, …
$ pneumopati <fct> NA, nao, nao, nao, nao, nao, NA, nao, NA, NA, NA, NA, nao, …
$ imunodepre <fct> NA, nao, nao, nao, nao, nao, NA, nao, NA, NA, NA, NA, nao, …
$ renal <fct> NA, nao, nao, nao, nao, nao, NA, nao, NA, NA, NA, NA, nao, …
$ obesidade <fct> NA, nao, nao, nao, nao, nao, NA, nao, NA, NA, NA, NA, nao, …
$ vacina_cov <fct> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ dose_1_cov <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ dose_2_cov <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ fab_cov_1 <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ fab_cov_2 <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ dt_entuti <date> NA, NA, NA, NA, NA, NA, NA, 2020-06-30, NA, 2020-07-12, NA…
$ dt_saiduti <date> NA, NA, NA, NA, NA, NA, NA, 2020-07-29, NA, NA, NA, NA, NA…
$ uti <fct> nao, nao, nao, nao, nao, nao, nao, sim, nao, sim, nao, nao,…
$ suport_ven <fct> "sim, nao invasivo", "nao", "nao", "sim, nao invasivo", "na…
$ evolucao <fct> cura, cura, cura, cura, cura, cura, cura, obito, cura, cura…
$ faixa_et <chr> "<20", "20-34", "20-34", "20-34", "20-34", ">=34", "20-34",…
$ dias_uti <drtn> NA days, NA days, NA days, NA days, NA days, NA days, NA d…
Pronto, temos nossa base completa e aprendemos um pouco sobre manipular dados. O pacote tidyverse
será um grande aliado seu no R de forma geral. Como mencionado anteriormente, não cobrimos tudo o que é necessário saber para trabalhar com manipulação de dados, é necessário entender a demanda e pesquisar soluções. Saber traduzir o seu problema para que consiga pesquisar com mais facilidade é uma habilidade muito importante. Recomendamos que treine, trabalhe com diferentes tipos de dados, pesquise pacotes, funções, etc. Com o tempo fará com tranquilidade coisas que hoje considera difícil. Lembre-se, a pratica leva a perfeição.