setwd("caminho_da_pasta/separado/dessa_forma") # selecionando a pasta
getwd() # verifica qual é o atual diretório
obj1=1 # obj1 recebe o inteiro '1'
obj1
## [1] 1
obj2="a" # obj2 recebe o caractere 'a' (sempre entre aspas simples ou composta)
obj2
## [1] "a"
obj3=T # obj3 recebe o booleano 'TRUE' ('FALSE' pode ser feito com 'F')
obj3
## [1] TRUE
obj4="caderno vermelho" #obj4 recebe a string 'caderno vermelho'
obj4
## [1] "caderno vermelho"
vetor1=c(1,2,3,4,5,6,7,8,9,10) # um vetor númerico formado por números de 1 a 10
vetor1
## [1] 1 2 3 4 5 6 7 8 9 10
vetor2=1:10 # um vetor igual ao 'vetor1'
vetor2
## [1] 1 2 3 4 5 6 7 8 9 10
vetor3=seq(from=11, to=20, by = 1) # sequencia de 11 a 20, de um a um
vetor3
## [1] 11 12 13 14 15 16 17 18 19 20
matriz1=matrix(vetor2,ncol=2,byrow = F)
# matrix numérica de 1 a 10, separado em 2 colunas ('ncol=2') e feita por coluna ('byrow=F' ou 'bycol=T')
matriz1
## [,1] [,2]
## [1,] 1 6
## [2,] 2 7
## [3,] 3 8
## [4,] 4 9
## [5,] 5 10
Uma matriz é a composição de um ou mais vetores, e pode ser ou somente numérica ou somente de caracteres (a mistura dos dois tipos somente poderá ser um data frame).
df1=data.frame("Vetor_1"=letters[1:5],"Vetor_2"=c(1:5),stringsAsFactors = F)
df1
## Vetor_1 Vetor_2
## 1 a 1
## 2 b 2
## 3 c 3
## 4 d 4
## 5 e 5
# 'StringAsFactor' é um booleano que indica se os vetores de caracteres serão fatores ou não
# Se 'T' (ou 'TRUE'), o 'Vetor_1' seria atribuído como fator, se 'F', continua como caractere
# letters é um objeto já existente no R, com o alfabeto em ordem crescente
lista1=list("Lista_Numerica"=seq(1,5,1),
"Lista_Caracteres"=c("a","Uma","diablo","~~kfk~~","PSIU"))
lista1
## $Lista_Numerica
## [1] 1 2 3 4 5
##
## $Lista_Caracteres
## [1] "a" "Uma" "diablo" "~~kfk~~" "PSIU"
# uma lista pode ser composta só de vetores ou só de matrizes, quanto de vetores e matrizes, e até mesmo dataframes
lista1[[1]] # acessando a primeira lista da lista1
## [1] 1 2 3 4 5
lista1[[2]][1] # acessando o primeiro elemento da segunda lista da lista1
## [1] "a"
Geralmente, trabalharemos com data frames, que nada mais são que tabelas, em que cada coluna é um vetor. Ou seja, o R basicamente trabalha com vetores.
Premissa importante: todo vetor para o R é um vetor coluna.
Transpor um vetor
vetor4 = t(vetor1)
vetor4
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
## [1,] 1 2 3 4 5 6 7 8 9 10
Operações aritméticas de vetores
# Soma: Soma do elemento da posição i do vetor j com o da posição i do vetor k
vetor4 = vetor1+vetor3
vetor4
## [1] 12 14 16 18 20 22 24 26 28 30
# Subtração: Diferença entre o elemento da posição i do vetor j e o da posição i do vetor k
vetor5 = vetor3-vetor1
vetor5
## [1] 10 10 10 10 10 10 10 10 10 10
# Multiplicação: Multiplicação do elemento da posição i do vetor j pelo elemento da posição i do vetor k
vetor6 = vetor4*vetor5
vetor6
## [1] 120 140 160 180 200 220 240 260 280 300
# Divisão: Divisão do elemento da posição i do vetor j pelo elemento da posição i do vetor k
vetor7 = vetor6/vetor5
vetor7
## [1] 12 14 16 18 20 22 24 26 28 30
# Potência: cada elemento do vetor i elevado a potência m
vetor8 = vetor1^2
vetor8
## [1] 1 4 9 16 25 36 49 64 81 100
# Raiz: raiz m de cada elemento do vetor i
vetor9 = vetor8^(1/2); sqrt(vetor8) # raiz quadrada
## [1] 1 2 3 4 5 6 7 8 9 10
vetor9
## [1] 1 2 3 4 5 6 7 8 9 10
# Resto: Resto da divisão do elemento da posição i do vetor j pelo elemento da posição i do vetor k
vetor10 = vetor1%%vetor3
vetor10
## [1] 1 2 3 4 5 6 7 8 9 10
Transpor uma matriz
matriz2 = t(matriz1)
matriz2
## [,1] [,2] [,3] [,4] [,5]
## [1,] 1 2 3 4 5
## [2,] 6 7 8 9 10
Operações aritméticas com matrizes
# Soma: Soma do elemento da posição (i,j) da matriz k com o elemento da posição (i,j) da matriz l. Tem que resultar em uma matriz da mesma dimensão das matrizes operadas.
matriz3 = matriz1+matriz1
matriz3
## [,1] [,2]
## [1,] 2 12
## [2,] 4 14
## [3,] 6 16
## [4,] 8 18
## [5,] 10 20
# Subtração: Diferença do elemento da posição (i,j) da matriz k com o elemento da posição (i,j) da matriz l. Tem que resultar em uma matriz da mesma dimensão das matrizes operadas.
matriz4 = matriz3-matriz1
matriz4
## [,1] [,2]
## [1,] 1 6
## [2,] 2 7
## [3,] 3 8
## [4,] 4 9
## [5,] 5 10
# Multiplicação: Multiplicação da linha i da matriz k com a coluna i da matriz l para gerar o elemento da posição (i,i). Feita com matrizes de dimensões transpostas. Resulta sempre em uma matriz quadrada (mesma quantidade de linhas e colunas).
matriz5 = matriz1%*%matriz2 # o operador %*% multiplica matrizes
matriz5
## [,1] [,2] [,3] [,4] [,5]
## [1,] 37 44 51 58 65
## [2,] 44 53 62 71 80
## [3,] 51 62 73 84 95
## [4,] 58 71 84 97 110
## [5,] 65 80 95 110 125
matriz1*matriz3 # aqui é a multiplicação elemento por elemento (as matrizes devem ter a mesma dimensão)
## [,1] [,2]
## [1,] 2 72
## [2,] 8 98
## [3,] 18 128
## [4,] 32 162
## [5,] 50 200
5*matriz1 # multiplicação de uma matriz por um escalar
## [,1] [,2]
## [1,] 5 30
## [2,] 10 35
## [3,] 15 40
## [4,] 20 45
## [5,] 25 50
# Divisão: Divisão do elemento da posição (i,j) da matriz k com o elemento da posição (i,j) da matriz l. Somente pode ser feita entre matrizes com mesma dimensão. Resulta sempre na mesma dimensão das matrizes operadas.
matriz6 = matriz1/matriz3
matriz6
## [,1] [,2]
## [1,] 0.5 0.5
## [2,] 0.5 0.5
## [3,] 0.5 0.5
## [4,] 0.5 0.5
## [5,] 0.5 0.5
# Matriz diagonal: matriz identidade multiplicado por um escalar
matriz7 = diag(5,5,5)
matriz7
## [,1] [,2] [,3] [,4] [,5]
## [1,] 5 0 0 0 0
## [2,] 0 5 0 0 0
## [3,] 0 0 5 0 0
## [4,] 0 0 0 5 0
## [5,] 0 0 0 0 5
# Determinante de uma matriz: Somente com matrizes quadradas
matriz8 = matrix(c(1,2,3,4),ncol=2)
det(matriz8)
## [1] -2
# Inversa de uma matriz: Somente com matrizes quadradas que tenham determinante
solve(matriz8)
## [,1] [,2]
## [1,] -2 1.5
## [2,] 1 -0.5
# Traço de uma matriz: Soma da diagonal de uma matriz
sum(diag(matriz8))
## [1] 5
# Autovalores e Autovetores
eigen(matriz8)
## eigen() decomposition
## $values
## [1] 5.3722813 -0.3722813
##
## $vectors
## [,1] [,2]
## [1,] -0.5657675 -0.9093767
## [2,] -0.8245648 0.4159736
Os condicionais if e else são usados em conjunto.
if(df1$Vetor_1[1]=="a"){
print(TRUE)
}else{
print(FALSE)
}
## [1] TRUE
if(df1$Vetor_1[1]!="a"){
print(TRUE)
}else{
print(FALSE)
}
## [1] FALSE
No primeiro if/else do exemplo acima queremos saber se o elemento da primeira posição da coluna Vetor_1 do data frame df1 é igual a letra a. Se sim, fazer print(TRUE)
, ou seja, mostrar TRUE na tela. No segundo if/else do exemplo, é exatamente o oposto.
Ou seja, o if/else serve para executar uma ação com base em condições estabelecidas, e se essas condições não forem aceitas, fazer outra ação.
Caso a ação for apenas a condição explicitada no if
, não necessariamente usamos o else
. Veja:
if(df1$Vetor_1[1]=="a"){
print(TRUE)
}
## [1] TRUE
Mesmo não tendo a função else
, a ação mostrar na tela TRUE foi executada.
Os loops são utilizados para passear por vetores. Normalmente estão atrelados aos condicionais, para então executarem uma ação.
Obs: Há necessidade, muitas vezes, da utilização de operadores lógicos. São eles:
==: operador de comparação (igualdade)
!=: operador de comparação (desigualdade)
||: operador ou (união)
&&: operador e (intersecção)
>: maior que
<: menor que
>=: maior ou igual
<=: menor ou igual
# Vamos percorrer pelo vetor1
for(i in 1:length(vetor1)){
print(vetor1[i])
}
## [1] 1
## [1] 2
## [1] 3
## [1] 4
## [1] 5
## [1] 6
## [1] 7
## [1] 8
## [1] 9
## [1] 10
# Vamos percorrer o mesmo vetor, mas agora tendo uma restrição
i=1
while (i<=5) {
print(vetor1[i])
i<-i+1
}
## [1] 1
## [1] 2
## [1] 3
## [1] 4
## [1] 5
Usando for
, fazemos com que i vá de 1 ao tamanho do vetor1 (função length
), e usamos o i de tal forma que mostre na tela o vetor1[1]
, vetor1[2]
… vetor1[10]
, incrementando de 1 em 1.
Usando while
, dizemos que enquanto i for menor ou igual a 5, mostrar na tela vetor1[1]
, vetor1[2]
… vetor1[5]
, com incremento de 1. O seu incremento é com base no que colocamos no código.
i=1
while (i<=5) {
print(vetor1[i])
i<-i+2
}
## [1] 1
## [1] 3
## [1] 5
Chamamos de aninhados os loops com condicionais.
for(i in 1:length(vetor1)){
if(vetor1[i]%%2==0){
print(vetor1[i])
}
}
## [1] 2
## [1] 4
## [1] 6
## [1] 8
## [1] 10
O exemplo acima “printa” na tela somente os valores pares do vetor1 (resto da divisão por 2 seja 0).
Faremos uma ação semelhante à função acima com a função ifelse
, apenas com uma linha de código, entretanto será impresso o dividendo correspondente caso for par e 0 caso for ímpar.
ifelse(vetor1%%2==0,vetor1,0)
## [1] 0 2 0 4 0 6 0 8 0 10
Podemos criar qualquer tipo de função, contanto que seja executável (sem erros de sintax).
Faremos aqui uma função em que o usuário tenha que responder pelo prompt.
ola1=function(){
cat("Você está bem? (sim ou nao)\n")
resp=scan(what = "character",n=1)
if(resp=="sim"){
cat("Que bom!")
}else{
cat("Você precisa dormir mais!")
}
}
Outra forma de fazer a mesma função:
ola2=function(){
print("Você está bem? (sim ou nao)\n")
resp=readLines(n=1)
if(resp=="sim"){
print("Que bom!")
}else{
print("Você precisa dormir mais!")
}
}
Faremos uma função que calcule a média de um vetor.
media=function(x){return(sum(x)/length(x))}
media(vetor1)
## [1] 5.5
As funções podem conter condicionais, loops e até loops aninhados. A próxima função mostrará na tela se um número é ímpar, par ou zero.
par_impar=function(x){
if(x%%2==0 && x!=0){
print("par")
}
if(x%%2!=0 && x!=0){
print("ímpar")
}
if(x==0){
print("zero")
}
}
par_impar(3)
## [1] "ímpar"
par_impar(324)
## [1] "par"
par_impar(0)
## [1] "zero"
Boas práticas: Se houver necessidade de criar funções, é considerado boa prática fazer em outro arquivo e na criação ou tratamento de dados usar source()
para chamar o arquivo .R
que contém as funções.
str(df1)
## 'data.frame': 5 obs. of 2 variables:
## $ Vetor_1: chr "a" "b" "c" "d" ...
## $ Vetor_2: int 1 2 3 4 5
df1$Vetor_1 # selecionando a coluna 'Vetor_1'
## [1] "a" "b" "c" "d" "e"
df1[,1] # selecionando a primeira coluna
## [1] "a" "b" "c" "d" "e"
df1$Vetor_1[2] # acessando a linha 2 da coluna 'Vetor_1'
## [1] "b"
df1[2,1] # acessando a linha 2 da coluna 1 ('Vetor_1')
## [1] "b"
vetor1<-append(vetor1,6)
vetor1
## [1] 1 2 3 4 5 6 7 8 9 10 6
vetor1<-append(vetor1,c(7,8,9,10))
vetor1
## [1] 1 2 3 4 5 6 7 8 9 10 6 7 8 9 10
vetor1[c(11:15)]<-11:15 # usando 'append' ou apenas indicando o local onde cada elemento entrará no vetor
vetor1
## [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
vetor1<-vetor1[-c(6:15)] # para retirar valores de um vetor (ou matriz), basta usar '-' antes do local onde o elemento está
vetor1
## [1] 1 2 3 4 5
df1[6,]<-c("f",6)
Em um data frame, ao adicionar novos valores, adicionamos só a linha (ou coluna), ou seja, não podemos adicionar somente um elemento (ou célula).
OBS: um vetor pode ser somente de um tipo específico (não dá para ter números e caracteres em um mesmo vetor). Veja:
c("a",2,3,4,"e") # todos os elementos são caracteres, mesmo adicionando os inteiros como numéricos
## [1] "a" "2" "3" "4" "e"
df1<-df1[-6,] # excluindo toda a linha 6
df1
## Vetor_1 Vetor_2
## 1 a 1
## 2 b 2
## 3 c 3
## 4 d 4
## 5 e 5
df1[-5,1] # excluindo a linha 5 da primeira coluna
## [1] "a" "b" "c" "d"
c(vetor1,vetor3)
## [1] 1 2 3 4 5 11 12 13 14 15 16 17 18 19 20
# Criando outro data frame
df2=data.frame("Vetor_1"=letters[6:10],"Vetor_2"=c(6:10),stringsAsFactors = F)
df2
## Vetor_1 Vetor_2
## 1 f 6
## 2 g 7
## 3 h 8
## 4 i 9
## 5 j 10
# Mesclando por linha (É necessário que os dois data frames possuam a mesma quantidade de colunas, com os mesmos nomes)
df3=rbind(df1,df2)
df3
## Vetor_1 Vetor_2
## 1 a 1
## 2 b 2
## 3 c 3
## 4 d 4
## 5 e 5
## 6 f 6
## 7 g 7
## 8 h 8
## 9 i 9
## 10 j 10
Uma mescla por coluna seria utilizando a função cbind
, mas para fazer isso é necessário que ambos contenham o mesmo número de linhas.
Obs: É possível mesclar um vetor (coluna ou linha) em um data frame utilizando estas mesmas funções.
Antes precisaremos instalar o pacote readxl
para leitura de dados de planilha excel (xls,xlsx).
install.packages("readxl") # instala pacote
Não existe problema em instalar um pacote que já tenha sido instalado. A última instalação subscreverá a anterior. Mas para saber se possui um pacote em questão basta executar find.package("nome_do_pacote")
.
library(readxl) # chama o pacote da sua biblioteca
Lendo o arquivo ‘Demanda’, do tipo ‘xlsx’:
tabela=read_excel("Demanda.xlsx",col_types = c("date",rep("numeric",4)))
tabela
## # A tibble: 1,545 x 5
## Periodo Dia.Semana Mes Ano `Volume Real Tt`
## <dttm> <dbl> <dbl> <dbl> <dbl>
## 1 2014-07-01 00:00:00 3 7 2014 1268185
## 2 2014-07-02 00:00:00 4 7 2014 1202998
## 3 2014-07-03 00:00:00 5 7 2014 1432447
## 4 2014-07-04 00:00:00 6 7 2014 1187383
## 5 2014-07-05 00:00:00 7 7 2014 1205782
## 6 2014-07-07 00:00:00 2 7 2014 1223325
## 7 2014-07-08 00:00:00 3 7 2014 1389747
## 8 2014-07-09 00:00:00 4 7 2014 1496877
## 9 2014-07-10 00:00:00 5 7 2014 1572148
## 10 2014-07-11 00:00:00 6 7 2014 1535039
## # ... with 1,535 more rows
Tibble nada mais é que um data frame com uma melhor visualização.
str(tabela) # classes das colunas do data frame
## tibble[,5] [1,545 x 5] (S3: tbl_df/tbl/data.frame)
## $ Periodo : POSIXct[1:1545], format: "2014-07-01" "2014-07-02" ...
## $ Dia.Semana : num [1:1545] 3 4 5 6 7 2 3 4 5 6 ...
## $ Mes : num [1:1545] 7 7 7 7 7 7 7 7 7 7 ...
## $ Ano : num [1:1545] 2014 2014 2014 2014 2014 ...
## $ Volume Real Tt: num [1:1545] 1268185 1202998 1432447 1187383 1205782 ...
colnames(tabela) # visualizo quais colunas o data frame possui
## [1] "Periodo" "Dia.Semana" "Mes" "Ano"
## [5] "Volume Real Tt"
head(tabela,5) # visualizo as 5 primeiras linhas do data frame
## # A tibble: 5 x 5
## Periodo Dia.Semana Mes Ano `Volume Real Tt`
## <dttm> <dbl> <dbl> <dbl> <dbl>
## 1 2014-07-01 00:00:00 3 7 2014 1268185
## 2 2014-07-02 00:00:00 4 7 2014 1202998
## 3 2014-07-03 00:00:00 5 7 2014 1432447
## 4 2014-07-04 00:00:00 6 7 2014 1187383
## 5 2014-07-05 00:00:00 7 7 2014 1205782
tail(tabela,5) # visualizo as 5 últimas linhas do data frame
## # A tibble: 5 x 5
## Periodo Dia.Semana Mes Ano `Volume Real Tt`
## <dttm> <dbl> <dbl> <dbl> <dbl>
## 1 2019-06-25 00:00:00 3 6 2019 1078119
## 2 2019-06-26 00:00:00 4 6 2019 1450389
## 3 2019-06-27 00:00:00 5 6 2019 1500218
## 4 2019-06-28 00:00:00 6 6 2019 1399839
## 5 2019-06-29 00:00:00 7 6 2019 952781
É possível, neste caso, verificar qual é a data inicial e a data final do banco de dados, bem como qual é o número máximo de semanas registrado no bd, ou qual é o volume mínimo e o máximo registrado, assim como sua média e mediana.
summary(tabela)
## Periodo Dia.Semana Mes Ano
## Min. :2014-07-01 00:00:00 Min. :2.000 Min. : 1.000 Min. :2014
## 1st Qu.:2015-09-30 00:00:00 1st Qu.:3.000 1st Qu.: 4.000 1st Qu.:2015
## Median :2017-01-03 00:00:00 Median :5.000 Median : 7.000 Median :2017
## Mean :2016-12-30 15:39:29 Mean :4.505 Mean : 6.533 Mean :2016
## 3rd Qu.:2018-03-31 00:00:00 3rd Qu.:6.000 3rd Qu.:10.000 3rd Qu.:2018
## Max. :2019-06-29 00:00:00 Max. :7.000 Max. :12.000 Max. :2019
## Volume Real Tt
## Min. : 182
## 1st Qu.: 987587
## Median :1202998
## Mean :1212538
## 3rd Qu.:1424660
## Max. :2788423
# Soma
sum(tabela$`Volume Real Tt`)
## [1] 1873371234
# Média
mean(tabela$`Volume Real Tt`)
## [1] 1212538
# Média ponderada: Um exemplo
pesos=c(0.25,0.50,0.25) # Soma = 1
tab=data.frame("UF"=c("BA","PE","MT"),"PMC"=c(90,85,94));tab
## UF PMC
## 1 BA 90
## 2 PE 85
## 3 MT 94
weighted.mean(tab$PMC,pesos) # Média Ponderada do PMC das UFs
## [1] 88.5
# Mediana
median(tabela$`Volume Real Tt`)
## [1] 1202998
# Variância
var(tabela$`Volume Real Tt`)
## [1] 138192518384
# Desvio Padrão (Mesma grandeza dos dados)
sd(tabela$`Volume Real Tt`) # ou sqrt(var)
## [1] 371742.5
# Valor Mínimo
min(tabela$`Volume Real Tt`)
## [1] 182
# Valor Máximo
max(tabela$`Volume Real Tt`)
## [1] 2788423
# Quartis: Dividir os dados em 25, 50 (mediana) e 75%
quantile(tabela$`Volume Real Tt`,probs=c(0.25,0.50,0.75))
## 25% 50% 75%
## 987587 1202998 1424660
## Moda: Não existe função própria no R, mas um exemplo de como fazê-lo
data(cars)
cars$speed # os dados já estão ordenados (para ordenar um vetor, usar função 'sort')
## [1] 4 4 7 7 8 9 10 10 10 11 11 12 12 12 12 13 13 13 13 14 14 14 14 15 15
## [26] 15 16 16 17 17 17 18 18 18 18 19 19 19 20 20 20 20 20 22 23 24 24 24 24 25
freq = table(cars$speed);freq # obtém a tabela com frequência dos elementos
##
## 4 7 8 9 10 11 12 13 14 15 16 17 18 19 20 22 23 24 25
## 2 2 1 1 3 2 4 4 4 3 2 3 4 3 5 1 1 4 1
names(table(cars$speed))[table(cars$speed) == max(table(cars$speed))]# obtém qual elemento aparece mais (moda)
## [1] "20"
# Outra forma de calcular a moda
moda<-function(x){return(names(sort(-table(as.vector(x))))[1])}
moda(cars$speed)
## [1] "20"
As funções da família Apply permitem que façamos várias operações sobre vetores.
apply: aplica uma função nas linhas ou colunas de uma tabela e retorna um vetor
apply(X = tabela[,-1],MARGIN = 2,FUN = "sum") # aplicando a soma(FUN="sum") por coluna (MARGIN=2)
## Dia.Semana Mes Ano Volume Real Tt
## 6960 10094 3115489 1873371234
lapply: aplica uma função em cada elemento de uma lista e retorna uma lista
lista2=list(a=1:10,b=11:20,c=21:30)
lapply(X=lista2,FUN="mean")
## $a
## [1] 5.5
##
## $b
## [1] 15.5
##
## $c
## [1] 25.5
sapply: aplica uma função em cada elemento de uma lista e retorna um vetor
sapply(X=lista2,FUN="sd")
## a b c
## 3.02765 3.02765 3.02765
mapply: aplica uma função em diferentes estruturas (vetor, matriz, etc.) de elemento em elemento.
mapply("sum",vetor1,vetor2) # o vetor1 tem tamanho 5 e o vetor2 tem tamanho 10, logo foi somado os elementos de 1 a 5 de ambos e os elementos restantes do vetor2 foram repetidos
## [1] 2 4 6 8 10 7 9 11 13 15
tapply: aplica uma função em um vetor que está definido por outro vetor
x=1:20
y=factor(rep(letters[1:5],4))
tapply(x,y,FUN="sum")
## a b c d e
## 34 38 42 46 50
Selecionar determinada informação pode ser custoso diretamente na base do R. Por exemplo, quero selecionar qual foi o volume de todos os meses de Abril. Usando a base do R faríamos:
tabela$`Volume Real Tt`[tabela$Mes==4]
## [1] 1331913 1539774 682779 960889 1378834 1469180 1474092 1441551 1179019
## [10] 1133140 1424746 1501562 1560327 1561032 1324994 1509249 66530 1735563
## [19] 1707474 1840708 1563914 1383993 2051720 2151474 2788423 942663 919502
## [28] 776296 1093186 1241803 1321381 1314603 1188492 971654 1218538 1334133
## [37] 1302426 1344691 1022135 1081720 1316609 1499411 1350826 1146109 1081155
## [46] 1259794 1505372 1464004 1557210 1696972 456504 356669 717957 903764
## [55] 846413 950622 752012 845006 1238275 1326383 1260852 5727 636963
## [64] 884076 1192642 1410272 1380747 130793 1059854 1019881 1359100 1492842
## [73] 1456617 1444493 1252412 144546 950957 1057762 1119035 1049476 835861
## [82] 797957 996534 1132330 1091259 1006510 823905 837064 1066871 1144376
## [91] 1167862 1130779 3282 1140393 1158796 1318647 1202444 1266035 971920
## [100] 1035702 582989 869226 879801 907282 957945 714122 685021 1109899
## [109] 1098980 1132921 1049811 782670 804080 1277500 1344211 1209850 12265
## [118] 797058 944604 1119783 1258777 1174808 1166129 984558 1035335 1385376
Existe um pacote que nos auxilia a resolver esse tipo de problema de forma mais intuitiva, o pacote dplyr
. Veja como seria fazer o mesmo filtro utilizando este pacote:
library(dplyr)
tabela %>% select(`Volume Real Tt`,Mes) %>% filter(Mes==4)
## # A tibble: 126 x 2
## `Volume Real Tt` Mes
## <dbl> <dbl>
## 1 1331913 4
## 2 1539774 4
## 3 682779 4
## 4 960889 4
## 5 1378834 4
## 6 1469180 4
## 7 1474092 4
## 8 1441551 4
## 9 1179019 4
## 10 1133140 4
## # ... with 116 more rows
O operador %>%
é utilizado para substituir o uso do parâmetro que define qual objeto será selecionado para o uso das funções. Normalmente é o primeiro parâmetro das funções.
Verficando qual é o dia da semana com o maior registro de volume e quando ocorreu.
tabela %>% select(Periodo,Dia.Semana,`Volume Real Tt`) %>% filter(`Volume Real Tt`==max(`Volume Real Tt`))
## # A tibble: 1 x 3
## Periodo Dia.Semana `Volume Real Tt`
## <dttm> <dbl> <dbl>
## 1 2015-04-30 00:00:00 5 2788423
Assim, podemos ver que 30/04/2015 foi o dia de maior volume registrado entre julho/14 e junho/19.
# Criando tabela hipotética de volume mensal por marca antes da atualização
tab1=data.frame("Periodo"=rep(seq(as.Date("2019-01-01"),as.Date("2019-06-01"),"month"),2),"Volume"=c(265447,225361,235695,245632,245871,236587,152632,125413,136585,145258,145263,144325),"Marca"=c(rep("Coca-cola",6),rep("Fanta",6)));tab1
## Periodo Volume Marca
## 1 2019-01-01 265447 Coca-cola
## 2 2019-02-01 225361 Coca-cola
## 3 2019-03-01 235695 Coca-cola
## 4 2019-04-01 245632 Coca-cola
## 5 2019-05-01 245871 Coca-cola
## 6 2019-06-01 236587 Coca-cola
## 7 2019-01-01 152632 Fanta
## 8 2019-02-01 125413 Fanta
## 9 2019-03-01 136585 Fanta
## 10 2019-04-01 145258 Fanta
## 11 2019-05-01 145263 Fanta
## 12 2019-06-01 144325 Fanta
# Tabela depois da atualização
tab2=data.frame("Periodo"=rep(seq(as.Date("2019-01-01"),as.Date("2019-06-01"),"month"),2),"Volume"=c(265447,225365,235689,245632,245874,236590,152630,125402,136585,145258,145262,144329),"Marca"=c(rep("Coca-cola",6),rep("Fanta",6)));tab2
## Periodo Volume Marca
## 1 2019-01-01 265447 Coca-cola
## 2 2019-02-01 225365 Coca-cola
## 3 2019-03-01 235689 Coca-cola
## 4 2019-04-01 245632 Coca-cola
## 5 2019-05-01 245874 Coca-cola
## 6 2019-06-01 236590 Coca-cola
## 7 2019-01-01 152630 Fanta
## 8 2019-02-01 125402 Fanta
## 9 2019-03-01 136585 Fanta
## 10 2019-04-01 145258 Fanta
## 11 2019-05-01 145262 Fanta
## 12 2019-06-01 144329 Fanta
# Sumarização da primeira tabela
gp1=tab1%>%group_by(Marca)%>%summarise(Vol_Medio_Anterior=mean(Volume));gp1
## # A tibble: 2 x 2
## Marca Vol_Medio_Anterior
## <chr> <dbl>
## 1 Coca-cola 242432.
## 2 Fanta 141579.
# Sumarização da segunda tabela
gp2=tab2%>%group_by(Marca)%>%summarise(Vol_Medio_Posterior=mean(Volume));gp2
## # A tibble: 2 x 2
## Marca Vol_Medio_Posterior
## <chr> <dbl>
## 1 Coca-cola 242433.
## 2 Fanta 141578.
# Verificando se as tabelas estão com os mesmos valores
gp=cbind(gp1,gp2[,2])
gp<-gp%>%select(Marca,Vol_Medio_Anterior,Vol_Medio_Posterior)%>%mutate("Diferença"=Vol_Medio_Anterior-Vol_Medio_Posterior);gp
## Marca Vol_Medio_Anterior Vol_Medio_Posterior Diferença
## 1 Coca-cola 242432.2 242432.8 -0.6666667
## 2 Fanta 141579.3 141577.7 1.6666667
A função summarise
é utilizada para resumir os dados de acordo com a variável selecionada para agrupamento, usando a função group_by
, e uma função a qual deseja-se sumarizar. No caso em questão, resumimos o volume pela média de cada marca dentro do período das tabelas.
Já a função mutate
serve para mudar uma tabela já existente, acrescentando uma coluna em função de outra(s) coluna(s), em que no exemplo, utilizamos a função para criar uma coluna com a diferença das duas colunas de volume médio anterior e posterior à atualização.
Um exemplo para a esta situação seria ordenar o volume em ordem decrescente (ou crescente). Veja como seria
tab3 = tabela %>% select(Periodo,`Volume Real Tt`) %>% arrange(-`Volume Real Tt`);tab3
## # A tibble: 1,545 x 2
## Periodo `Volume Real Tt`
## <dttm> <dbl>
## 1 2015-04-30 00:00:00 2788423
## 2 2014-12-30 00:00:00 2584947
## 3 2014-12-23 00:00:00 2433226
## 4 2014-12-19 00:00:00 2409500
## 5 2014-12-29 00:00:00 2341274
## 6 2016-12-30 00:00:00 2334924
## 7 2014-12-31 00:00:00 2314538
## 8 2014-11-28 00:00:00 2300092
## 9 2014-12-18 00:00:00 2278882
## 10 2014-12-27 00:00:00 2270514
## # ... with 1,535 more rows
# Para fazer em ordem crescente basta retirar o sinal de menos
Vemos que o dia 30 de abril de 2015 pode ser considerado um dia atípico, dado o fato de que todos os dias logo abaixo dele são de dezembro de 2014.
Para agilizarmos esse processo utilizaremos o pacote tidyr
.
library(tidyr)
Usaremos um exemplo de um bd da base do R. Para carregar qualquer bd do diretório do R basta usar o comando data("nome do bd")
.
data("USArrests")
head(USArrests)
## Murder Assault UrbanPop Rape
## Alabama 13.2 236 58 21.2
## Alaska 10.0 263 48 44.5
## Arizona 8.1 294 80 31.0
## Arkansas 8.8 190 50 19.5
## California 9.0 276 91 40.6
## Colorado 7.9 204 78 38.7
São dados dos Estados Unidos sobre crimes acontecidos numa determinada época. Faremos o seguinte: Iremos transformar a tabela em questão numa tabela transversal, em que as variáveis estarão em uma coluna e os valores em outra, variando apenas o estado.
USArrests$State <- rownames(USArrests) # criando uma coluna com os nomes dos estados
head(USArrests)
## Murder Assault UrbanPop Rape State
## Alabama 13.2 236 58 21.2 Alabama
## Alaska 10.0 263 48 44.5 Alaska
## Arizona 8.1 294 80 31.0 Arizona
## Arkansas 8.8 190 50 19.5 Arkansas
## California 9.0 276 91 40.6 California
## Colorado 7.9 204 78 38.7 Colorado
usa.long = USArrests %>% gather(key="Crime", value="Valor",-State )
head(usa.long)
## State Crime Valor
## 1 Alabama Murder 13.2
## 2 Alaska Murder 10.0
## 3 Arizona Murder 8.1
## 4 Arkansas Murder 8.8
## 5 California Murder 9.0
## 6 Colorado Murder 7.9
Assim, Crime é uma variável categórica, tendo os fatores Murder, Assault, UrbanPop e Rape. Já a variável Valor é uma variável numérica. Cada State tem o registro de qual crime aconteceu e quantos foram.
Para fazer o inverso, transformar linhas em colunas, basta utilizar a função spread
.
usa.wide = usa.long %>% spread(key="Crime", value="Valor")
head(usa.wide)
## State Assault Murder Rape UrbanPop
## 1 Alabama 236 13.2 21.2 58
## 2 Alaska 263 10.0 44.5 48
## 3 Arizona 294 8.1 31.0 80
## 4 Arkansas 190 8.8 19.5 50
## 5 California 276 9.0 40.6 91
## 6 Colorado 204 7.9 38.7 78
Utilizada quando se tem duas informações em uma mesma variável. Usaremos a tabela Demanda como exemplo, dividindo o Periodo em dia, mês e ano. Esta função permite apenas divisão de uma variável em duas, e como temos 3 informações na variável Periodo, temos que antes fazer um procedimento para que a informação do dia não seja excluída.
library(stringr)
tabela$Periodo <- str_replace(tabela$Periodo,"-","/")
head(tabela$Periodo)
## [1] "2014/07-01" "2014/07-02" "2014/07-03" "2014/07-04" "2014/07-05"
## [6] "2014/07-07"
No procedimento acima, utilizamos o pacote stringr
, utilizado para manipulação de strings (veremos logo mais), para podermos substituir o primeiro - por /, para então dividirmos a coluna Periodo em duas, sem perder a informação do dia.
tab4 = tabela %>% select(Periodo,`Volume Real Tt`) %>% separate(Periodo,sep="/",into = c("Ano","Mês"))
head(tab4)
## # A tibble: 6 x 3
## Ano Mês `Volume Real Tt`
## <chr> <chr> <dbl>
## 1 2014 07-01 1268185
## 2 2014 07-02 1202998
## 3 2014 07-03 1432447
## 4 2014 07-04 1187383
## 5 2014 07-05 1205782
## 6 2014 07-07 1223325
Então agora podemos dividir a coluna Mês em duas: Mês e Dia.
tab5 = tab4 %>% separate(`Mês`,sep="-",into = c("Mês","Dia"))
head(tab5)
## # A tibble: 6 x 4
## Ano Mês Dia `Volume Real Tt`
## <chr> <chr> <chr> <dbl>
## 1 2014 07 01 1268185
## 2 2014 07 02 1202998
## 3 2014 07 03 1432447
## 4 2014 07 04 1187383
## 5 2014 07 05 1205782
## 6 2014 07 07 1223325
Voltando agora o separador da variável Periodo da tabela.
tabela$Periodo <- str_replace(tabela$Periodo,"/","-")
head(tabela$Periodo)
## [1] "2014-07-01" "2014-07-02" "2014-07-03" "2014-07-04" "2014-07-05"
## [6] "2014-07-07"
Vamos fazer exatamente o oposto do que fizemos anteriormente, até chegarmos na variável Periodo.
Primeiro, uniremos as colunas Mês e Dia, depois uniremos com o Ano e teremos a coluna Periodo novamente.
tab6 = tab5 %>% unite("Mes_Dia","Mês","Dia",sep="-")
head(tab6)
## # A tibble: 6 x 3
## Ano Mes_Dia `Volume Real Tt`
## <chr> <chr> <dbl>
## 1 2014 07-01 1268185
## 2 2014 07-02 1202998
## 3 2014 07-03 1432447
## 4 2014 07-04 1187383
## 5 2014 07-05 1205782
## 6 2014 07-07 1223325
tab7 = tab6 %>% unite("Periodo","Ano","Mes_Dia",sep="-")
head(tab7)
## # A tibble: 6 x 2
## Periodo `Volume Real Tt`
## <chr> <dbl>
## 1 2014-07-01 1268185
## 2 2014-07-02 1202998
## 3 2014-07-03 1432447
## 4 2014-07-04 1187383
## 5 2014-07-05 1205782
## 6 2014-07-07 1223325
De um vetor de strings
vect1=c("maçã","amora","goiaba","maçã","goiaba","mamão")
vect2=unique(vect1)
vect2
## [1] "maçã" "amora" "goiaba" "mamão"
De uma tabela
tab8=data.frame("x"=c(1,1,4,5,3,3,6),
"y"=c(2,2,2,2,2,2,2))
distinct(tab8,x,.keep_all = T)
## x y
## 1 1 2
## 2 4 2
## 3 5 2
## 4 3 2
## 5 6 2
O pacote principal para manipulação de strings é o stringr
, que mostrei a vocês no bloco anterior. Mostrarei algumas funcionalidades.
Obs: Para ver todas as funções de um pacote, basta digitar nome_do_pacote::
e apertar a tecla Tab no RStudio. Você conseguirá ver não só as funções, como também o resumo do Help (parâmetros, descrição dos parâmetros, etc.). Para ver o Help completo, basta executar o comando ?função_ou_pacote
.
# Exemplo de string
st1="Quem canta os males espanta."
# Extraindo o sobrenome
st2=str_sub(st1,start=12)
st2
## [1] "os males espanta."
# Forma otimizada
st3=str_sub(st1,str_locate(st1,"o")[1])
st3
## [1] "os males espanta."
A função acima extrai uma string com base na posição que o primeiro caractere se encontra na string anterior. Obs: O espaço também é um caractere.
Como foi extraído a última string do objeto st1
, bastou-se utilizar o parâmetro start
. Entretando se a opção é extrair no meio do objeto, deve-se utilizar o parâmetro end
.
Existe uma outra função, semelhante a esta: str_extract
, porém extrai apenas os caracteres colocados como parâmetro.
str_extract(st1,"os males espanta")
## [1] "os males espanta"
Trabalhar com strings necessita o conhecimento do que é REGEX, ou Expressões Regulares, que são notações para representar padrões em strings. Obs: Para mais informações, acesse http://turing.com.br/material/regex/introducao.html .
Vimos um exemplo disto no bloco anterior, entretando vamos rever para melhor fixação.
# Exemplo 1
st4=c("onde tiver amor, haverá paz")
st4
## [1] "onde tiver amor, haverá paz"
# Substituindo o 'á' por 'a'
st5=str_replace(st4,"á","a")
st5
## [1] "onde tiver amor, havera paz"
# Exemplo 2
st6=c("quero sorvete e chocolate")
st6
## [1] "quero sorvete e chocolate"
# Substituindo 'sorvete' por 'açaí'
st7=str_replace(st6,"sorvete","açaí")
st7
## [1] "quero açaí e chocolate"
# Exemplo 3
st8=c("três pratos de trigo para três tigres tristes")
st8
## [1] "três pratos de trigo para três tigres tristes"
# Substituindo todas as repetições de 'três' por 'quatro'
st9=str_replace_all(st8,"três","quatro")
st9
## [1] "quatro pratos de trigo para quatro tigres tristes"
A função str_replace_all
faz a mesma coisa que a função str_replace
, mas para todas as vezes em que a string, ou caractere, se repetir.
st10=str_remove(st7,"açaí e ")
st10
## [1] "quero chocolate"
st11=str_remove_all(st9,"quatro ")
st11
## [1] "pratos de trigo para tigres tristes"
st12=c("Adam","Bruno","Camila","Daniel","Helena","Vitória")
st13=c("Adam","Daniel","Helena","Vitória","Sabrina","Samuel")
str_detect(st12,st13)
## [1] TRUE FALSE FALSE FALSE FALSE FALSE
Nessa situação, a função está detectando se os elementos da mesma posição de st12 e st13 são iguais. Mas vemos que Daniel está presente nos dois vetores, assim como Helena e Vitória. Faremos então com que a função str_detect
verifique se os nomes de um vetor estão ou não no outro vetor, através de um loop for.
for(i in 1:length(st12)){
for(j in 1:length(st13)){
if(str_detect(st12[i],st13[j])==TRUE){
print(st13[j])
}
}
}
## [1] "Adam"
## [1] "Daniel"
## [1] "Helena"
## [1] "Vitória"
Guardando em um vetor seria:
st14=vector()
for(i in 1:length(st12)){
for(j in 1:length(st13)){
if(str_detect(st12[i],st13[j])==TRUE){
st14<-append(st14,st13[j])
}
}
}
st14
## [1] "Adam" "Daniel" "Helena" "Vitória"
# Separando a string 'st1' em duas
st1
## [1] "Quem canta os males espanta."
st15=str_split(st1," ",simplify = T) # simplify = T indica que queremos que a string seja "splitada" em uma matriz (Se F, seria uma lista)
st15
## [,1] [,2] [,3] [,4] [,5]
## [1,] "Quem" "canta" "os" "males" "espanta."
Temos agora ao invés de uma string com a frase inteira, 5 strings em um vetor. Entretanto, a função str_split
transforma o vetor em uma lista por default, mas como utilizamos o parâmetro simplify = T
, temos uma matriz 1x5. Para transformar em um vetor, basta utilizar o comando as.vector(objeto)
.
st15<-as.vector(st15)
st15
## [1] "Quem" "canta" "os" "males" "espanta."
st16=c("AQUI SOMOS UM")
# Tornar todas as letras da string minúsculas
st17=str_to_lower(st16)
st17
## [1] "aqui somos um"
# Tornar todas as letras da string maiúsculas
st18=str_to_upper(st17)
st18
## [1] "AQUI SOMOS UM"
# Tornar a primeira letra de cada string maiúscula
st19=str_to_title(st17)
st19
## [1] "Aqui Somos Um"
# Tornar a primeria letra da primeira string maiúscula
st20=str_to_sentence(st19)
st20
## [1] "Aqui somos um"
A função que utilizaremos para concatenar strings faz parte da base do R, é a função paste
.
vetor11 = "a história é a seguinte:"
vetor12="era uma vez aquilo lá!"
paste(vetor11,vetor12,sep=" ") #fazendo com separador
## [1] "a história é a seguinte: era uma vez aquilo lá!"
paste0(vetor11,vetor12) #fazendo sem separador
## [1] "a história é a seguinte:era uma vez aquilo lá!"
Muitas vezes, temos a necessidade de juntar duas planilhas, cujo alguns valores são os mesmos. Por exemplo, uma planilha que já tenhamos com informações passadas de volume por SKU e queremos atualizar ela com base em uma planilha vindo direto da UXT com novas colunas, também por SKU.
Simplesmente mesclando da forma que mostrei anteriormente não resolveria o problema porque teríamos uma mesma SKU repetida. Nesse caso, a ferramenta a ser mostrada resolveria este problema.
Irei apresentar a função full_join
com base em um bd já existente no R.
band_members
## # A tibble: 3 x 2
## name band
## <chr> <chr>
## 1 Mick Stones
## 2 John Beatles
## 3 Paul Beatles
band_instruments
## # A tibble: 3 x 2
## name plays
## <chr> <chr>
## 1 John guitar
## 2 Paul bass
## 3 Keith guitar
band_members %>% full_join(band_instruments,by=c("name"="name"))
## # A tibble: 4 x 3
## name band plays
## <chr> <chr> <chr>
## 1 Mick Stones <NA>
## 2 John Beatles guitar
## 3 Paul Beatles bass
## 4 Keith <NA> guitar
Usando essa função, juntamos todas as informações das planilhas, tendo elas as mesmas colunas ou não. Neste exemplo a chave das duas tabelas está com o mesmo nome name
, entretanto existem situações em que apenas os nomes diferem, mas as informações são as mesmas. Por isso usar o parâmetro by
, que é onde indicamos qual é a chave de cada planilha.
Para juntar somente as mesmas informações das chaves, utilizaremos a função inner_join
.
band_members %>% inner_join(band_instruments,by=c("name"="name"))
## # A tibble: 2 x 3
## name band plays
## <chr> <chr> <chr>
## 1 John Beatles guitar
## 2 Paul Beatles bass
Para mantermos os dados do conjunto a esquerda e os registros a direita que coincidirem com a chave usamos a função left_join
.
band_members %>% left_join(band_instruments,by=c("name"="name"))
## # A tibble: 3 x 3
## name band plays
## <chr> <chr> <chr>
## 1 Mick Stones <NA>
## 2 John Beatles guitar
## 3 Paul Beatles bass
Para fazermos o contrário, usamos a função right_join
.
band_members %>% right_join(band_instruments,by=c("name"="name"))
## # A tibble: 3 x 3
## name band plays
## <chr> <chr> <chr>
## 1 John Beatles guitar
## 2 Paul Beatles bass
## 3 Keith <NA> guitar
Fim!