#https://github.com/Toniiiio/imageclipr
test1 = c(1,2,3)
test = as.data.frame(test1, row.names = c('Test', 'test1','test3'))
#library(cluster, lib.loc = "C:\Users\Rafael Oliveira\Documents\R\win-library\4.0")
# library(boot)
# library(dplyr)
# detach("package::boot", unload =TRUE)
# install.packages("")
# ls()
A=c(1,2,3,4,5,6,7)
1:20 #cria a sequencia por passos de 1 unidade
## [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
20:1 # cria a sequencia por passos de 1 unidade de reversa
## [1] 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
seq(1,20, by=2) #slicing 2 de cada vez
## [1] 1 3 5 7 9 11 13 15 17 19
seq(1,20, length.out=50) #cria 50 numeros (com decimais) de 1 até 20
## [1] 1.000000 1.387755 1.775510 2.163265 2.551020 2.938776 3.326531
## [8] 3.714286 4.102041 4.489796 4.877551 5.265306 5.653061 6.040816
## [15] 6.428571 6.816327 7.204082 7.591837 7.979592 8.367347 8.755102
## [22] 9.142857 9.530612 9.918367 10.306122 10.693878 11.081633 11.469388
## [29] 11.857143 12.244898 12.632653 13.020408 13.408163 13.795918 14.183673
## [36] 14.571429 14.959184 15.346939 15.734694 16.122449 16.510204 16.897959
## [43] 17.285714 17.673469 18.061224 18.448980 18.836735 19.224490 19.612245
## [50] 20.000000
#; para colocar varios parametros. Fazemos operaçoes elemento a elemento
a=c(1,2)
b=c(5,10)
c=c(-1,-5,0)
d=c(1,2,3,4)
a+b;a-b;a*b;a/b
## [1] 6 12
## [1] -4 -8
## [1] 5 20
## [1] 0.2 0.2
a+c;b+d
## Warning in a + c: longer object length is not a multiple of shorter object
## length
## [1] 0 -3 1
## [1] 6 12 8 14
#R faz reciclagem do vetor mais pequeno - Numa operação entre dois vetores de tamanhos diferentes, o mais pequeno é “reciclado” de forma a atingir o tamanho do maior e assim ser executada a operação
#Quando vetor nao tem tamanho multiplo do mais pequeno - longer object is nota multiple of shorter object lenght
#Quando vetor maior tem tamanho multiplo do mais pequeno (tamanho 4 e 2, respetivamente, por exemplo) nao dá aviso no termial (exemplo do a+d)
a*b
## [1] 5 20
d*d
## [1] 1 4 9 16
d^2
## [1] 1 4 9 16
c*d
## Warning in c * d: longer object length is not a multiple of shorter object
## length
## [1] -1 -10 0 -4
#produto interno soma vetores, produto de elemento guarda em vetores
a%*%b #produto interno de vetores
## [,1]
## [1,] 25
#a = [a1,a2]
#b = [b1,b2]
#a*b = a1b1 + a2b2
a = c(1,2)
b = c(1,5)
c=c(-1,3)
a>b #comparaçoes entre vetores sao feitas entre elemento a elemento consoante os seus respetivos indices. Neste caso vai dar [FALSE, FALSE]
## [1] FALSE FALSE
a>=b
## [1] TRUE FALSE
a==b
## [1] TRUE FALSE
a!=b
## [1] FALSE TRUE
###Disjunçao, Conjunçao, Negaçao
#TRUE = 1
#FALSE = 0
a>b & a>c #FALSE + FALSE
## [1] FALSE FALSE
a>b | a>c
## [1] TRUE FALSE
!(a>b) #would be the same as saying "a<b"
## [1] TRUE TRUE
#E
#TT da T, TF da F, FT da F e FF da F
#OU
#TT da T, TF da T, FT da T FF da F
sum(a>b & a>c) #R interpreta logica de forma numerica onde T é 1 e F é 0;
## [1] 0
#Neste caso da 0, logo, nao ha nenhum elemento de a que seja superior a b ou a c. Diz-nos se há pelo menos 1 elemento (ou nenhum)
sum(a>b | a>c) #O a consegue ser superior a primeira componente do b, logo, dá 1. Como o operador é "ou" basta que 1 seja verdade para validar o pressuposto
## [1] 1
#which #quais os indices (posiçoes) do vetor x que são TRUE
which(a>b);which(a>c)
## integer(0)
## [1] 1
any(a)# avaliar se ha algum elemento de X que é True ou nao. Para fazer o contrario fazemos !any(x) (se ha algum elemento de x que é false ou nao)
## Warning in any(a): coercing argument of type 'double' to logical
## [1] TRUE
any(a>b);any(a>c)
## [1] FALSE
## [1] TRUE
all(a) #retorna falso quando pelo menos 1 dos elementos do vetor é falso
## Warning in all(a): coercing argument of type 'double' to logical
## [1] TRUE
all(a>b);all(a>c) #FALSO e FALSE - O 1º retorna false pois temos 2 falsos e no 2º retorna false pois temos pelo menos um false
## [1] FALSE
## [1] FALSE
!all(a>b)
## [1] TRUE
all(!(a>b))
## [1] TRUE
table(a) #contagem frequencias
## a
## 1 2
## 1 1
# São criados por concatenação de expressões entre aspas:
a = c("expressão1","expressão2")
a
## [1] "expressão1" "expressão2"
# A função paste permite concatenar ﴾reciclando se necessário﴿ um número arbitrário de argumentos ﴾caracteres ou não﴿ um por um definindo o separador entre eles #como se fosse o .format no python ou as template strings no javascript
#paste(arg1,arg2,sep=",")
paste("Teste", a[2])
## [1] "Teste expressão2"
paste("Neste momento são",date())
## [1] "Neste momento são Thu Dec 30 22:34:24 2021"
Definem grupos de valores, previamente especificados
Criados pela função factor() e os grupos por si definidos podem ser obtidos com a função levels()
x = factor(c("Suficiente","Bom", "Bom", "Suficiente"))
x
## [1] Suficiente Bom Bom Suficiente
## Levels: Bom Suficiente
levels(x) #Vai mostrar apenas os valores unicos (nao repete os valores de x). Funçao que vai ao x para ir buscar os levels
## [1] "Bom" "Suficiente"
Podemos ainda definir a ordem desejada dos niveis:
y=factor(c("Bom","Suficiente", "Bom", "Suficiente"),
levels = c("Suficiente","Bom")) # este levels é uma opçao dentro do factor
y
## [1] Bom Suficiente Bom Suficiente
## Levels: Suficiente Bom
Os valores pre-especificados podem tambem nao estar no vetor em causa:
z=factor(c("Suficiente", "Bom", "Bom", "Suficiente"),
levels = c("Insuficiente","Suficiente","Bom")) #ao fazer grafico podemos ver que nao teriamos a barra do insuficiente
#levels = as.character(1:100)
#sort - ordem alfabetica
#sort(decreasing=True); -> ao contrario
?sort
## starting httpd help server ... done
z
## [1] Suficiente Bom Bom Suficiente
## Levels: Insuficiente Suficiente Bom
A função table() permite obter um resumo das frequencias absolurtas de cada grupo de um fator. Para usar as frequencias relativas devemos usar prop.table(table(factor))
table(z)
## z
## Insuficiente Suficiente Bom
## 0 2 2
prop.table(table(z))
## z
## Insuficiente Suficiente Bom
## 0.0 0.5 0.5
A função tapply permite aplica uma funçao a cada grupo de elementos de um objecto (grupos definidos por um fator). Vai no fundo aplicar uma determinada transformaçao definida por uma funçao tapply(objeto,fator,função). O resultado corresponde à soma dos elementos de x agrupados pelos niveis de z. Aplica uma funçao a um objeto demonstrando o resultado consoante os fatores existentes.
Ex: Grupo etario, peso e queremos calcular media do peso. Podemos calcular media global, ou media dos jovens, adultos e seniors (fatores) de forma separada com o tapply
x=c(10,8,5,4)
tapply(x,z,sum) #soma elementos do vetor x que fazem parte de cada um dos grupos que estao definidos em z -> 10 + 4 para a mesma posiçao em indice do vetor z ([1] e [4] sao suficiente e [2] e [3] sao bom). O resultado da soma dá 14 para suficiente (10+4 das posiçoes 1 e 4) e 13 para bom (8 e 5 nas posiçoes 2 e 3). O tamanho dos vetores tem de ser iguais para comparar os indices
## Insuficiente Suficiente Bom
## NA 14 13
length(x) #para obter o comprimento do vetor x
## [1] 4
max(x) #ou min(x) para obter o valor máximo e mínimo, respetivamente, do vetor x
## [1] 10
sum(x) #para obter a soma de todos os elementos de x
## [1] 27
prod(x) #para obter o produto de todos os elementos de x
## [1] 1600
sort(x) #para ordenar os elementos de x por ordem crescente
## [1] 4 5 8 10
sort(x,decreasing=TRUE) #para ordem decrescente﴿
## [1] 10 8 5 4
Podemos também introduzir missing values usando a expressão NA; o resultado das operações anteriores(exceto length) em vetores com NA é NA
Criar novos vetores mais compridos, concatenando vetores já existentes usando a função c()
a=c(1,2)
B=3:10
c(a,B)
## [1] 1 2 3 4 5 6 7 8 9 10
Podemos replicar um determinado vetor usando rep()
n = 2
m = 3
rep(x,n) #ou:
## [1] 10 8 5 4 10 8 5 4
rep(x,times=n) #concatena n replicações de x
## [1] 10 8 5 4 10 8 5 4
rep(x,each=m) #concatena m replicações de cada elemento de x - pega no primeiro elemento do vetor x e replica 4 vezes, pega no segundo elemento e faz o mesmo... "Por cada elemento no vetor X, replicar N vezes)
## [1] 10 10 10 8 8 8 5 5 5 4 4 4
rep(x,times=n,each=m) #mistura das anteriores
## [1] 10 10 10 8 8 8 5 5 5 4 4 4 10 10 10 8 8 8 5 5 5 4 4 4
rep(x,length.out=10) #replica x com eventual reciclagem até um comprimento de n. Vetor tem comprimento 3 (original) e faz 3 replicaçoes inteiras e depois so falta uma posiçao ate termos 10 (pega no primeiro elemento do X e completa o que falta)
## [1] 10 8 5 4 10 8 5 4 10 8
Para selecionar um subconjunto de elementos de um determinado vetor, usamos o comando x[vetor de indices]
A definição do vetor de índices pode ser realizada usando:
x=c(10,-32,40)
tf=c(F,F,T)
x[tf]
## [1] 40
x[c(1,3)]
## [1] 10 40
x[-c(1,3)] #diz que nao queremos escolher os elementos no indice 1 nem no indice 3
## [1] -32
namesx=c(3,1,4,2,5,6,8,7,9)
x
## [1] 3 1 4 2 5 6 8 7 9
x[3]
## [1] 4
x[c(3,5,8)]
## [1] 4 5 7
x[-c(3,5,8)] #todos menos os elementos do indice 3,5,8
## [1] 3 1 2 6 8 9
x[x>3] #Vai ao X e retorna quais os que sao superiores a 3
## [1] 4 5 6 8 7 9
x>3 # Verfica quais deles sao superiores a 3
## [1] FALSE FALSE TRUE FALSE TRUE TRUE TRUE TRUE TRUE
x[(x%%2)==0] #retorna os pares cuja divisao da resto 0
## [1] 4 2 6 8
x[!(x%%2)==0] #retorna os impares - Negaçao
## [1] 3 1 5 7 9
(x%%2)==0
## [1] FALSE FALSE TRUE TRUE FALSE TRUE TRUE FALSE FALSE
Tambem podemos usar a indexação para modificar elementos de um vetor com x[vetor de indices] = novos valores
Notas: * se novos valores é escalar, então a todos os elementos selecionados de x é atribuído esse valor
x
## [1] 3 1 4 2 5 6 8 7 9
aux = x[x>3]
x[x>3]=10
x
## [1] 3 1 10 2 10 10 10 10 10
x[x>3]= aux
x
## [1] 3 1 4 2 5 6 8 7 9
x[(x%%2)==0]=c(0,-1) #substitui todos os pares por 0 e -1, respetivamente
x
## [1] 3 1 0 -1 5 0 -1 7 9
se novos valores é um vetor com comprimento superior a x, apenas os seus primeiros length(x[vetor de indices]) valores são utilizados
se novos valores é um vetor com comprimento inferior a x, então é reciclado até length(x[vetor de indices])
Matriz
Podem ser criadas com o comando matrix(x,nrow,ncol) organizando os valores de x por coluna em nrow linhas e ncol colunas (com a opção byrow=TRUE preenche por linha)
A=matrix(1:12,nrow = 4,ncol = 3)
A
## [,1] [,2] [,3]
## [1,] 1 5 9
## [2,] 2 6 10
## [3,] 3 7 11
## [4,] 4 8 12
B=matrix(1:12,nrow=4,ncol=3,byrow=TRUE) #preencher por linha
B
## [,1] [,2] [,3]
## [1,] 1 2 3
## [2,] 4 5 6
## [3,] 7 8 9
## [4,] 10 11 12
A[2:3]
## [1] 2 3
B[,2] #todos os elementos da 2º coluna
## [1] 2 5 8 11
B[4,] #todos os elementos da 4ª linha
## [1] 10 11 12
B[2:4,2:3]#da linha 2 â 4 e da coluna 2 a 3
## [,1] [,2]
## [1,] 5 6
## [2,] 8 9
## [3,] 11 12
B[c(1,3),1] #Linha 1 e linha 3 da coluna 1
## [1] 1 7
dim(A) #obtém a dimensão ﴾nº linhas e nº de colunas﴿ de A
## [1] 4 3
t(A) #obtém a transposta de A
## [,1] [,2] [,3] [,4]
## [1,] 1 2 3 4
## [2,] 5 6 7 8
## [3,] 9 10 11 12
ncol(A); nrow(A) # o número de colunas e linhas, respetivamente, de A
## [1] 3
## [1] 4
A * B #obtém o produto elemento a elemento entre as matrizes. Multiplicaçao elemento a elemento
## [,1] [,2] [,3]
## [1,] 1 10 27
## [2,] 8 30 60
## [3,] 21 56 99
## [4,] 40 88 144
#A%*%B #obtém o produto matricial usual entre as matrizes. Numero de colunas de A tem que ser igual a numero de linhas da B, por isso é que executando isto dá erro. Temos que fazer a transposta de uma delas para conseguir
#Produto matricial -> 1*1 + 5*2 + 9 * 3 (elemento das linhas de A * elemento das colunas de B e a sua soma)
A%*% t(B)
## [,1] [,2] [,3] [,4]
## [1,] 38 83 128 173
## [2,] 44 98 152 206
## [3,] 50 113 176 239
## [4,] 56 128 200 272
diag(A) #para obter as entradas da diagonal de A (quando sao quadradas)
## [1] 1 6 11
k = 4
diag(4) #com k inteiro positivo, cria a matriz identidade de dimensão k. Matriz identidade que só tem 0, com exceçao da diagonal. Mtriz identidade é a matriz neutra (1 é o elemento neutro da multiplicaçao)
## [,1] [,2] [,3] [,4]
## [1,] 1 0 0 0
## [2,] 0 1 0 0
## [3,] 0 0 1 0
## [4,] 0 0 0 1
Forma de matriz com varias dimensoes
Para criar uma array usamos o comando array(x,dim) onde x é um vetor contendo as entidades e dim é um vetor especificando as dimensoes pretendidas (o preenchimento ocorre por coluna)
É efetuada reciclagem no caso de x não conter elementos suficientes para preencher todas as posições do array
x=1:12
array(x,dim=c(2,3,3))
## , , 1
##
## [,1] [,2] [,3]
## [1,] 1 3 5
## [2,] 2 4 6
##
## , , 2
##
## [,1] [,2] [,3]
## [1,] 7 9 11
## [2,] 8 10 12
##
## , , 3
##
## [,1] [,2] [,3]
## [1,] 1 3 5
## [2,] 2 4 6
Podemos também criar um array a partir de x, forçando a alteração das suas dimensões: dim(x)=c(a,b,c,...) ﴾o vetor x transforma‐se no array﴿
a×b×c×· · · ﴾não é efetuada reciclagem﴿#dim(x)=c(2,3,3) #a array tem que ter as mesmas dimensoes de x, neste caso, 12 (na array estamos a tentar passar para dimensao 18)
dim(x)=c(1,6,2)
x
## , , 1
##
## [,1] [,2] [,3] [,4] [,5] [,6]
## [1,] 1 2 3 4 5 6
##
## , , 2
##
## [,1] [,2] [,3] [,4] [,5] [,6]
## [1,] 7 8 9 10 11 12
A[dim1,dim2,dim3,...] onde dim1, dim2, etc são vetores índice para cada uma das dimensões do arrayX=1:18
dim(X)=c(3,2,3)
X
## , , 1
##
## [,1] [,2]
## [1,] 1 4
## [2,] 2 5
## [3,] 3 6
##
## , , 2
##
## [,1] [,2]
## [1,] 7 10
## [2,] 8 11
## [3,] 9 12
##
## , , 3
##
## [,1] [,2]
## [1,] 13 16
## [2,] 14 17
## [3,] 15 18
X[2,1,3]
## [1] 14
X[c(2,3),1,2]
## [1] 8 9
X[,,1]
## [,1] [,2]
## [1,] 1 4
## [2,] 2 5
## [3,] 3 6
X[-1,,3]
## [,1] [,2]
## [1,] 14 17
## [2,] 15 18
X[(X%%2)==0]
## [1] 2 4 6 8 10 12 14 16 18
Coleções ordenadas de objetos, nao necessariamente do mesmo tipo, criadas assim: A = list(nome1=objeto1, nome2=objeto2...)
#Sem atribuir nomes:
L1 = list(1:3,"a",c(TRUE,FALSE,TRUE),c(2.3, 5.9))
str(L1)
## List of 4
## $ : int [1:3] 1 2 3
## $ : chr "a"
## $ : logi [1:3] TRUE FALSE TRUE
## $ : num [1:2] 2.3 5.9
names(L1)
## NULL
A$nomedoobjetoA[[indice]], onde indice é um inteiro positivo (diferente de A[indice])A[[indice do array]][indice], onde em index se aplicam as mesmas regras de indexação de arrays. [] retorna a lista enquanto que [[]] retorna o conteudo.L2=list(Obj1=1:3,Obj2="a",Obj3=c(TRUE,FALSE,TRUE),Obj4=c(2.3,5.9))
names(L2)
## [1] "Obj1" "Obj2" "Obj3" "Obj4"
L2$Obj3
## [1] TRUE FALSE TRUE
L2[[3]] #podemos chamar pelo nome do elemento ou o indice do elemento
## [1] TRUE FALSE TRUE
L2[3]
## $Obj3
## [1] TRUE FALSE TRUE
L2[[3]][2] # entra no objeto 3 e vai buscar o 2º elemento
## [1] FALSE
L2[3][2]
## $<NA>
## NULL
A[[indice]] = novo objeto ou A[indice] = list(novo objeto)names(A)[indice] = novo nomeA[indice novo] = list(nome=objeto)c(A,B,C...)L2[[2]] = c("a", "b")
L2
## $Obj1
## [1] 1 2 3
##
## $Obj2
## [1] "a" "b"
##
## $Obj3
## [1] TRUE FALSE TRUE
##
## $Obj4
## [1] 2.3 5.9
names(L2) #nome dos objetos por ordem
## [1] "Obj1" "Obj2" "Obj3" "Obj4"
names(L2)[3] = "Objeto 3"
L2[5] = list(pi)
names(L2)[5] = "Objeto 5"
str(L2)
## List of 5
## $ Obj1 : int [1:3] 1 2 3
## $ Obj2 : chr [1:2] "a" "b"
## $ Objeto 3: logi [1:3] TRUE FALSE TRUE
## $ Obj4 : num [1:2] 2.3 5.9
## $ Objeto 5: num 3.14
Linhas representam os casos e colunas as variaveis recolhidas
Uma data frame é uma lista em que cada objeto vai representar uma variavel. Nas data frames cada coluna deve ter o mesmo numero de elementos (valores para 150 pacientes, por exemplo)
Colunas devem ter nomes (das variaveis, nas listas chamam-se objetos).
data.frame(nomevar1=valores, nomevar2=valores, ...)
df1 = data.frame(var1 = 1:3, var2 = c("a", "b", "c"), row.names= c("Identificador1", "Identificador2", "Identificador3")) #temos 3 linhas e 2 variaveis. Podemos adicionar como factor em vez de chr
str(df1)
## 'data.frame': 3 obs. of 2 variables:
## $ var1: int 1 2 3
## $ var2: chr "a" "b" "c"
df1
## var1 var2
## Identificador1 1 a
## Identificador2 2 b
## Identificador3 3 c
#identificadores de pacientes, por exemplo, podem ser usados no "indice" de cada linha (que nao é uma variavel). Os row names pode ser nomes de genes, identificadores de pacientes, etc
###Indexação de data frames Data frame é como se fosse matriz misturada com caracterisitcas de uma lista
df1$var1; df1[,1]
## [1] 1 2 3
## [1] 1 2 3
df1$var2[2]; df1[2,2] #vai a variavel 2 e dentro desta variavel vai buscar o elemento na posiçao 2
## [1] "b"
## [1] "b"
Podemos referenciar diretamente o nome das colunas
#var2[2] #nao resulta
attach(df1) #para entrar no df1 e buscar o var2 podemos usar o $, mas para evitar esta parte fazemos o attach da data frame. Este attach vai abrir o df1 - colunas de df1 estao diretamente acessiveis
var2[2]
## [1] "b"
#Este metodo nao é o melhor principalmente se tivermos data frames com as mesmas variaveis
detach(df1)
names(df1) #obtém os nomes das colunas ﴾variáveis﴿ da data frame A
## [1] "var1" "var2"
colnames(df1) #é semelhante ao anterior
## [1] "var1" "var2"
rownames(df1) #obtém os nomes das linhas de A
## [1] "Identificador1" "Identificador2" "Identificador3"
cbind(df1,df1) #concatena as colunas de A com as colunas de B ﴾A e B têm de ter o mesmo número de linhas﴿
## var1 var2 var1 var2
## Identificador1 1 a 1 a
## Identificador2 2 b 2 b
## Identificador3 3 c 3 c
rbind(df1,df1) #concatena as linhas de A com as linhas de B ﴾A e B têm de ter o mesmo número e nome de colunas﴿
## var1 var2
## Identificador1 1 a
## Identificador2 2 b
## Identificador3 3 c
## Identificador11 1 a
## Identificador21 2 b
## Identificador31 3 c
df2 = df1 #vai criar indices novos (1...)
# names(df2)[2] = "var3" #vai dar erro pois o numero de variaveis em df1 e df2 vai ser diferente
# rbind(df1,df2)
cbind(arg1,arg2,arg3,…) - concatena horizontalmente os objetos ﴾do mesmo tipo﴿ arg1, arg2, arg3, etc; para tal, deverão ter o mesmo número de linhas
rbind(arg1,arg2,arg3,…) - concatena verticalmente os objetos ﴾do mesmo tipo﴿ arg1, arg2, arg3, etc; para tal, deverão ter o mesmo número de colunas
No caso de alguns argumentos serem vetores com dimensão desadequada, são automaticamente reciclados
Int, logic, char…
Se precisarmos de saber qual o modo podemos perguntar: is.??() e diz se é true ou false (onde ?? = numeric, character…)
Podemos ainda alterar (coerce) o tipo usando as.??() (onde ?? = numeric, character, data.frame…)
is.numeric(df1$var1)
## [1] TRUE
Podemos usar datasets para testes com data(package = .packages(all.available = TRUE)) e data()
x = data("EuStockMarkets")
x
## [1] "EuStockMarkets"
readxl e/ou xlsxrange(A1:C11) vai escolher as 3 primeiras variaveis e as primeiras 10 colunas (colocamos 11 pois a primeira linha tambem conta que é o header)col_types=c("numeric") para importar as colunas como numericas?read_excel
## No documentation for 'read_excel' in specified packages and libraries:
## you could try '??read_excel'
#swimming_pools = read.csv("D:/swimming_pools.csv")
#swimming_pools = read.csv("D:/swimming_pools.txt", sep=" ") #separa por espaços
readr# sp_text = read.csv(...)
?read.csv #first column as names
Podemos usar read.table("ficheiro") ou read.table(file, opção1=valor, opção2=valor,...) destacando-se as seguintes opções:
header=valor lógico indicando se a primeira linha do ficheiro contém os nomes das variáveissep="separador" indicando qual o separador entre colunas ﴾para separação por espaço, deixar em branco﴿quote="caractere" indicando o caractere envolvente dos valores das variáveisdec="." indicando qual o separador decimal utilizado no ficheirorow.names=vetor para especificar um vetor com os nomes das linhas ou o número da coluna contendo esses nomescol.names=vetor para especificar um vetor com os nomes das variáveisnrows=valor para especificar o número de linhas a importarskip=valor para especificar o número de linhas a ignorar antes de importarPara exportar uma base de dados (matriz ou data frame) usamos comando write.table - write.table(objeto,"ficheiro",opções)
Destacam-se as seguintes opções: * append valor lógico para indicar se o objeto é adicionado ao ficheiro * quote valor lógico ou vetor numérico para indicar, no primeiro caso, se as colunas de modo character ou factor são ”quoted”; no segundo caso, o vetor indica as colunas a aplicar quotes * sep para definir o separador entre colunas * dec para definir a separação decimal
#write.table(S1,"LE.txt", sep=":")
#write.table(S1,"LE1.txt", sep=":", row.names=F) #vai retirar os indices de cada linha
#S1
#save.image guarda tudo
#save(S1,file="S1.RData")
Executa instruções dependendo do valor logico de uma expressao
if (expr1) { expr2 }
onde expr1 representa uma condição ﴾lógica﴿ a ser verificada e expr2 é uma instrução ou conjunto de instruções a serem executadas caso expr1 for verdadeira
a=5
if (a>2) {
a+10 #temos que colocar print() para mostrar resultados intermedios
a+50
}
## [1] 55
a = 1
if (a>2) {
a+10
a+50
}
Na execução anterior, verifica‐se que apenas o último resultado é apresentado; caso expr2 contenha várias instruções que importa visualizar o resultado, podemos usar a função print()
Podemos também ter interesse em executar um conjunto de instruções caso expr1 seja falsa
if (expr1) { expr2 } else { expr3 }
onde expr3 é executada se expr1 for falsa
&& ﴾AND﴿ e || ﴾OR﴿ são normalmente usados em vez de & e |, respetivamente, por uma questão de eficiência ﴾evitam a avaliação da segunda expressão caso não seja necessário﴿a=1
if (a>2 && a<=5) { #por questao de eficiencia como o python se for F no && nao lemos o 2º
print(a+10)
print(a+50)
} else {
print("O valor de a não está entre 2 e 5")
}
## [1] "O valor de a não está entre 2 e 5"
if (expr1) { executar1 } else if (expr2) { executar2 } else if (expr3) { executar3 } else { executar4 }
x = 0
if (x < 0) {
print("Número negativo")
} else if (x > 0) {
print("Número positivo")
} else {
print("Zero")
}
## [1] "Zero"
.
x= -2
if (x<=-2) {
print(x**2)
} else if (x > -2 && x <5 ) {
print(exp(x))
} else {
print(x/2)
}
## [1] 4
Usadas para executar repetições ﴾ciclos﴿ de um determinado número de instruções: for, while, repeat
Para o ciclo for
for (nome in expr1) { expr2 }
onde nome representa uma variável incrementadora ﴾índice﴿, expr1 é tipicamente uma sequência numérica e expr2 as instruções a executar;
for (i in 1:6) {
print(i)
}
## [1] 1
## [1] 2
## [1] 3
## [1] 4
## [1] 5
## [1] 6
#for (i in aux)...
Para o ciclo while while (expr1) { expr2 } onde expr1 representa uma condição que, enquanto verdadeira, implica a execução das instruções em expr2;
i=0
while (i<=5) {
i=i+1
print(i)
}
## [1] 1
## [1] 2
## [1] 3
## [1] 4
## [1] 5
## [1] 6
i = 0
while (i<=3) {
i=runif(1,0,5) # 1 numero aleatorio entre 0 e 5. Semelhante ao sample?
print(i)
}
## [1] 1.684002
## [1] 2.883149
## [1] 2.884999
## [1] 4.015532
Para o ciclo repeat:
repeat { expr1 } onde expr1 é o conjunto de instruções a executar
breaki=0
repeat {
i=i+1
if (i==7) {
break
}
print(i)
}
## [1] 1
## [1] 2
## [1] 3
## [1] 4
## [1] 5
## [1] 6
A sua estrutura básica é da forma nome = function(arg1,arg2,…) {expr} onde nome é, como o próprio indica, o nome que pretendemos para a função, arg1, arg2 são argumentos ﴾objetos por exemplo﴿ passados para o “interior” da função e expr é o conjunto de instruções a executar
Numa função, os argumentos podem ser dados sob qualquer ordem desde que nomeados, caso contrário devem ser dados pela ordem definida na função
Exemplo: dada a função
funLE = function(x,y,z,w) {expr}
onde x e y são números, z é um valor lógico e w é uma string qualquer, podemos executá‐la das seguintes formas:
funLE(1,2,TRUE,"blue")funLE(w="blue",x=1,z=TRUE,y=2)funLE(1,2,w="blue",z=TRUE)É comum ocorrerem argumentos que o utilizador utiliza com maior frequência com um determinado valor
Nesse sentido, é possível estabelecer valores default que poupam o utilizador de os definir sempre que usa a função
Exemplo: suponhamos que na função anterior se pretende estabelecer como default que z=TRUE e w="blue"; então definimos
funLE = function(x,y,z=TRUE,w="blue") {expr}
x e y não têm valores default pelo que têm sempre de ser fornecidos; z e w se não forem fornecidos vão ser considerados como TRUE e “blue”, respetivamente
Assim, são equivalentes as seguintes execuções: funLE(1,2), funLE(1,2,TRUE,"blue") ou funLE(1,2,w="blue"); já funLE(1,2,z=FALSE) altera um dos defaults
A função break pode ser usada para terminar uma função, mas desde que dentro de um ciclo for, while ou repeat; para outras situações, usar a função stop
funlog = function(x,y,out=TRUE, pl=FALSE) {
if (x+y<=0) {
stop("x+y nao é positivo")
}
z=log(x+y) #so vamos para aqui se o numero for positivo, caso contrario, paramos o if statement pois nao podemos usar numeros negativos no log
if (out) {# mostrar valor de z se for true
print(z)
}
if (pl) { # so faz o plot se for true
plot(x+y,z)
}
}
funlog(1,2)
## [1] 1.098612
funlog(1,2,FALSE)
#funlog(-2,1) - Error in funlog(-2, 1) : x+y nao é positivo
funlog(1,2,pl=TRUE)
## [1] 1.098612
funlog(1,2,FALSE, TRUE)
#Exercício: altere a função de modo a que x e y possam ser vetores numéricos.
Muitas vezes as funções criadas contêm outras funções às quais necessitamos de passar parâmetros
Isso é possível utilizando o argumento … ﴾dot‐dot‐dot ou ellipsis ﴿
fun = function(x,y,z,...) {expr1 outrafunc(arg1,arg2,...) expr2}
onde expr1 e expr2 são instruções a executar e outrafunc é uma outra função a executar com argumentos arg1 e arg2 ﴾eventualmente criados em expr1 ou dados como entrada explícita na função principal﴿
Desta forma o R sabe que quaisquer parâmetros ou objetos passados para além de x,y,z serão destinados a outra função chamada internamente que também deverá conter o argumento …
Semelhante ao spread operator no javascript ou o *args ou **kwargs no python Exemplo:
funLE1 = function(x,y,...) {
z = x+y
plot(x,y)
mean(x,...)
}
funLE1(c(1,2,3,4,5,60),c(3,1,5,4,7,3))
## [1] 12.5
funLE1(c(1,2,3,4,5,60),c(3,1,5,4,7,3),trim=0.4)
## [1] 3.5
O argumento … permite passar argumentos para outras funções que sejam executadas na função funLE1
funLE1(c(1,2,3,4,5,60),c(3,1,5,4,7,3))
funLE1(c(1,2,3,4,5,60),c(3,1,5,4,7,3),trim=0.4)
O argumento trim é assim passado para a função mean
As funções retornam apenas o último objeto criado; para retornar vários objetos, constrói‐se ﴾por exemplo﴿ uma lista na última instrução da função
funlog3 = function(x,y,out=TRUE){
aux=c(x+y,x*y,x-y)
if (any(aux<=0)) { # garantir que qualquer uma das operaçoes no vetor é positivo
stop("argumento não positivo")
}
z1=log(x+y);z2=log(x*y);z3=log(x-y)
if (out) {
print(z1)
}
list(soma=z1,produto=z2,diferença=z3) # para exportar as variaveis de forma local (dentro da funçao) para modo global (Acesso global)
}
funlog3(2:10,1:9)
## [1] 1.098612 1.609438 1.945910 2.197225 2.397895 2.564949 2.708050 2.833213
## [9] 2.944439
## $soma
## [1] 1.098612 1.609438 1.945910 2.197225 2.397895 2.564949 2.708050 2.833213
## [9] 2.944439
##
## $produto
## [1] 0.6931472 1.7917595 2.4849066 2.9957323 3.4011974 3.7376696 4.0253517
## [8] 4.2766661 4.4998097
##
## $diferença
## [1] 0 0 0 0 0 0 0 0 0
A =funlog3(2:10,1:9) #a vantagem de ter uma lista no final é que podemos aceder as variaveis com o $
## [1] 1.098612 1.609438 1.945910 2.197225 2.397895 2.564949 2.708050 2.833213
## [9] 2.944439
A$soma
## [1] 1.098612 1.609438 1.945910 2.197225 2.397895 2.564949 2.708050 2.833213
## [9] 2.944439
A$produto
## [1] 0.6931472 1.7917595 2.4849066 2.9957323 3.4011974 3.7376696 4.0253517
## [8] 4.2766661 4.4998097
A$diferença
## [1] 0 0 0 0 0 0 0 0 0
Variável ‐ característica mensurável ou atributo de interesse para estudo na população *Ex: presença da doença; idade em que foi diagnosticada a doença
Uma amostra pode conter mais de uma característica de interesse para cada uma das unidades observadas. Com duas características temos uma amostra bivariada; com mais do que duas temos uma amostra multivariada.
Podemos definir dois grupos de variáveis quantitativas:
A frequência de um determinado valor é uma medida do número de vezes que esse valor ocorre
Se uma variável tem um grande número de diferentes valores ﴾quantitativa contínua﴿ então convém agrupar os dados em classes
Em geral, são calculadas as:
O cálculo de frequências acumuladas ﴾Ni e Fi﴿ pressupõe a existência de ordem nos valores, pelo que o seu cálculo não se aplica a variáveis nominais
Nao faz sentido calcular as frequencias acumuladas numa nominal (preto, azul, amarelo.. ordem nao interessa) pois estas acumuladas pressupoe que ha uma ordem (ordinais).
Para variáveis não contínuas ﴾discretas ou qualitativas, portanto﴿ podemos usar uma combinação dos comandos table, cumsum e prop.table
prop.table pega nas frequencias absolutas e vai calcular em proporçao %
cumsum faz a soma acumulada
Freq_rel_acum=cumsum(prop.table(tbl)) soma das frequencias relativas acumuladasFreq_acum=cumsum(tbl) guardar na variavel como a somaFreq_rel=prop.table(tbl) calcular frequencias relativasload("C:/Users/Rafael/Desktop/main/University/BioinformaticaClinica/1Semestre/LE/Material 2021/Scripts/LE-Fichas/DQ.RData")
tbl = table(dados$Escolaridade)
tbl
##
## Primaria Escolaridade obrigatoria Liceu e Curso Superior
## 17 60 23
cbind(Freq=tbl,
Freq_acum=cumsum(tbl),
Freq_rel=prop.table(tbl),
Freq_rel_acum=cumsum(prop.table(tbl)))
## Freq Freq_acum Freq_rel Freq_rel_acum
## Primaria 17 17 0.17 0.17
## Escolaridade obrigatoria 60 77 0.60 0.77
## Liceu e Curso Superior 23 100 0.23 1.00
.
Para variáveis contínuas começamos por definir as classes e tudo o resto é semelhante
#Para as continuas primeiro criamos as classes
classes=table(cut(dados$PAS,
breaks=nclass.Sturges(dados$PAS))) #numero de classes baseado na variavel dados$PAS
classes
##
## (110,114] (114,118] (118,122] (122,126] (126,129] (129,133] (133,137] (137,141]
## 1 0 1 3 7 25 41 22
cbind(Freq=classes,Freq.acum=cumsum(classes), Freq.rel=prop.table(classes), Freq.rel.acum=cumsum(prop.table(classes)))
## Freq Freq.acum Freq.rel Freq.rel.acum
## (110,114] 1 1 0.01 0.01
## (114,118] 0 1 0.00 0.01
## (118,122] 1 2 0.01 0.02
## (122,126] 3 5 0.03 0.05
## (126,129] 7 12 0.07 0.12
## (129,133] 25 37 0.25 0.37
## (133,137] 41 78 0.41 0.78
## (137,141] 22 100 0.22 1.00
#freq.rel.acum -> 12% tem uma PAS menor ou igual a 129
breaks=c(a,b,c,…) onde a,b,c,… são os extremos dos intervalosTambém podemos fazer o cruzamento de duas ou mais variáveis qualitativas, numa tabela de dupla entrada
table(dados$Gr_etario,dados$Escolaridade)
##
## Primaria Escolaridade obrigatoria Liceu e Curso Superior
## Ate aos 34 anos 3 9 4
## 35 - 64 anos 12 40 16
## 65 e mais anos 2 11 3
prop.table(table(dados$Gr_etario,dados$Escolaridade))
##
## Primaria Escolaridade obrigatoria Liceu e Curso Superior
## Ate aos 34 anos 0.03 0.09 0.04
## 35 - 64 anos 0.12 0.40 0.16
## 65 e mais anos 0.02 0.11 0.03
ftable(xtabs(~Gr_etario+Escolaridade,data=dados))
## Escolaridade Primaria Escolaridade obrigatoria Liceu e Curso Superior
## Gr_etario
## Ate aos 34 anos 3 9 4
## 35 - 64 anos 12 40 16
## 65 e mais anos 2 11 3
+## Medidas Amostrais ### Media vs Mediana vs Media aparada
Podemos agrupar as medidas amostrais em três grupos * Medidas de Localização Central * Central: Média, Mediana, Moda, Média Aparada
Relativa: Mínimo, Máximo, Quantis
O R possui vários comandos de base para obter as medidas de localização de uma variável x
mean(x) ou mean(x,trim=valor) para obter a média ou média aparada respetivamente ﴾valor varia entre 0 e 0.5﴿
median(x)` para obter a mediana
max(x) e min(x) para obter os valores máximo e mínimo, respetivamente
quantile(x) ou quantile(x,probs=vetor) para obter os quantis ﴾vetor contém valores em [0,1]﴿
summary(x) para obter um resumo ﴾simplificado﴿ de todas estas medidas
names(which(x == max(x))) para obter a moda de uma tabela usando rep() - exercicio 3,e,i) ficha 2
Não existe um comando imediato para obter a moda; pode ser identificada analisando a tabela de frequências
Muitas vezes interessa calcular determinadas medidas por grupos de indivíduos; para tal podemos usar a função tapply ou by:
quantile(dados$Peso, probs=c(0.1,0.3,0.8,0.95))
## 10% 30% 80% 95%
## 64.003 66.788 73.810 77.483
tapply(dados$PAS,dados$Gr_etario, mean) #no tapply podemos definir as nossas proprias funçoes em vez de ter as pre-estabelecidas como mean, summary, etc
## Ate aos 34 anos 35 - 64 anos 65 e mais anos
## 127.1875 134.7500 138.7500
by(dados$PAS,dados$Gr_etario, mean)
## dados$Gr_etario: Ate aos 34 anos
## [1] 127.1875
## ------------------------------------------------------------
## dados$Gr_etario: 35 - 64 anos
## [1] 134.75
## ------------------------------------------------------------
## dados$Gr_etario: 65 e mais anos
## [1] 138.75
by(dados$PAS,dados$Gr_etario, median)
## dados$Gr_etario: Ate aos 34 anos
## [1] 129
## ------------------------------------------------------------
## dados$Gr_etario: 35 - 64 anos
## [1] 135
## ------------------------------------------------------------
## dados$Gr_etario: 65 e mais anos
## [1] 139
by(dados$PAS,dados$Gr_etario, summary)
## dados$Gr_etario: Ate aos 34 anos
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 110.0 126.5 129.0 127.2 130.0 134.0
## ------------------------------------------------------------
## dados$Gr_etario: 35 - 64 anos
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 125.0 133.0 135.0 134.8 136.0 140.0
## ------------------------------------------------------------
## dados$Gr_etario: 65 e mais anos
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 135.0 138.0 139.0 138.8 139.2 141.0
max(x)-min(x) para obter a amplitudeIQR(x) para obter a distância inter‐quartilsd(x) para obter o desvio‐padrãovar(x) ou sd(x)^2 para obter a variânciamad(x) para obter o desvio absoluto mediano - Comparar o sd com o mad pode ajudar para ver se temos valores extremos (outliers)skewness do pacote momentsMedida que permite analisar o grau de relaçao (associaçao) linear entre 2 variaveis to coeficiente de correlaçao linear (coeficientes de correlaçao variam de -1 e 1)
Um valor negativo ﴾positivo﴿ indica que a relação é negativa ﴾positiva﴿, ou seja, com o aumento dos valores de uma variável verifica‐se uma ﴾um﴿ diminuição ﴾aumento﴿ dos valores da outra
Corr.=1 ou Corr.=‐1 significa correlação perfeita positiva ou negativa, respetivamente
O coeficiente de correlação de Pearson é calculado para duas variáveis medidas numa escala de intervalos ou razões ﴾Quantitativa vs Quantitativa﴿
O coeficiente linear de Spearman, RS, aplica‐se no caso de duas variáveis medidas pelo menos numa escala ordinal ﴾adequado para o caso Ordinal vs Ordinal﴿
O coeficiente de Kendall é uma alternativa ao coeficiente de Spearman quando existem empates entre as ordens das observações
No caso de uma amostra multivariada, podemos calcular uma matriz de correlações, constituída por todos os pares de correlações entre as várias variáveis
cor(dados$PAS,dados$PAD,method="pearson")
## [1] 0.9691827
cor(dados$PAS,dados$PAD,method="spearman")
## [1] 0.946051
cor(dados$PAS,dados$PAD,method="kendall")
## [1] 0.855748
# Matriz de correlações (apenas as variáveis numéricas)
View(cor(dados[,sapply(dados,is.numeric)])) #so faz correlaçao de variaveis numericas logo neste codigo estamos a fazer a correlaçao de todas as colunas de dados cujas colunas sao numericsa (sapply vai a data frame dados e verfica se é numerica). Como estamos a fazer indexaçao so vai considerar aquelas que tem true (numericas)
#Processo devia estar como row.names (index) e nao como variavel
#Correlaçao negativa- quanto maior a altura, menor o IMC
barplot(), geralmente associado ao comando table: barplot(table(x));também com plot(f) onde f é um fatorbarplot(table(dados$Escolaridade))
plot(dados$Escolaridade)
hist(x)
breaks para fornecer informação sobre a divisão em classes ﴾pode ser um vetor com os pontos de divisão, uma função para calcular os pontos de divisão, uma estimativa para o número de divisões, etc﴿hist(dados$PAS)
hist(dados$PAS,breaks = nclass.Sturges(dados$PAS))
hist(dados$PAS,breaks = 15)
Outliers ‐ Observações discrepantes ou extremas * devidas a erros de leitura ou medição ﴾corrigir se possível﴿ * valores reais ﴾nada a fazer?﴿ * Estas observações causam problemas! Enviesamento de futuras análises
Multimodalidade ‐ “picos” mais salientes; várias modas ou classes modais são indicadores de possíveis grupos distintos nos dados
Usado principalmente nas quantitativas (continuas e discretas).
Localização central: mediana
Localizações relativas: 1º e 3º quartis e mínimo e máximo.
Dispersão: amplitude e distância inter‐quartil
Assimetria: posição relativa da mediana na caixa e o comprimento dos bigodes
Uteis para comparar varias amostras (mesma variavel medida em diferentes grupos)
No R colocamos boxplot(x) Para caixa de bigodes comparativas boxplot(x,y,z...) Se alguma das variaveis é um fator (definindo por isso, grupos) entao boxplot(x ~ grp) ou plot(grp,x) tambem gera um boxplot comparativo (x é a variavel a analisar e grp é o fator)
boxplot(dados$PAS)
boxplot(dados$PAS,dados$PAD)
boxplot(dados$PAS~dados$Gr_etario)
plot(dados$Gr_etario, dados$PAS)
O diagrama de dispersão é uma representação gráfica, dos pares de pontos (x, y) de uma amostra bivariada. Este tipo de gráficos permitem relacionar duas variáveis entre si.
Diagrama de dispersao entre as variaveis x e y plot(x,y)
NOTA sao este tipo de graficos que fazemos para ver se ha uma relaçao linear entre as 2 variaveis quantitativas (ver se faz sentido fazer uma regressao, etc)
plot(dados$PAS,dados$PAD)
Sendo dificil a analise de uma matriz de correlaçao, podemos optar por analise grafica
library(corrplot) #apenas para testar correlaçoes lineares
## corrplot 0.90 loaded
dados1=dados[,-1] # Para excluir a variável Processo
corrplot(cor(dados1[,sapply(dados1,is.numeric)])) # passamos a matriz de correlaçao e depois temos uma funçao sapply que aplica is.numeric coluna a coluna. Escolhemos apenas as colunas de dados1 que sao numericas para fazer as correlaçoes dados1[row, column]. em que queremos dados[todas as linhas, das colunas que sao numericas] - é por isso que deixamos as linhas vazias
Quando os dados são recolhidos sobre os mesmos sujeitos em diferentes momentos temporais ﴾ao longo do tempo﴿ dizemos que estamos perante um problema de dados longitudinais ﴾ou medidas repetidas﴿
Geralmente neste tipo de dados pretende‐se analisar a evolução de uma qualquer característica com o tempo, eventualmente sujeita a um qualquer “tratamento”
Desta forma, os dados podem ser vistos como séries temporais para cada sujeito e a visualização pode ser feita por sujeito, por grupo, por valor médio, entre outras
Em geral os dados podem ser apresentados em dois formatos: formato “long” e formato “wide”
#install.packages("HSAUR3")
library(HSAUR3)
## Warning: package 'HSAUR3' was built under R version 4.0.5
## Loading required package: tools
data("epilepsy")
head(epilepsy,10) # Estes dados estão no formato long - pacote lattice pressupoe que os dados estao em formato long
## treatment base age seizure.rate period subject
## 1 placebo 11 31 5 1 1
## 110 placebo 11 31 3 2 1
## 112 placebo 11 31 3 3 1
## 114 placebo 11 31 3 4 1
## 2 placebo 11 30 3 1 2
## 210 placebo 11 30 5 2 2
## 212 placebo 11 30 3 3 2
## 214 placebo 11 30 3 4 2
## 3 placebo 6 25 2 1 3
## 310 placebo 6 25 4 2 3
lattice dispõe de ferramentas para visualização destes dados ﴾assumindo o formato “long”﴿ nos chamados Trellis plots#install.packages("lattice")
library(lattice)
## Warning: package 'lattice' was built under R version 4.0.5
xyplot(seizure.rate/base ~ period, data = epilepsy) #seizure.rate/base para todos os sujeitos para cada um dos periodos (59 sujeitos para periodo 1, 59 para periodo 2... mas temos mistura com os de placebo e tratamento e tambem nao sabemos a ligaçao entre sujeitos por cada um dos periodos. A bolinha no topo do periodo 1 nao é a mesma que a bolinha no topo do periodo 2.
xyplot(seizure.rate/base ~ period | treatment, data = epilepsy) #Este permite distinguir por tratamento. Os casos extremos (pessoas com muitas seizures) parecem ter reduzido. A concentraçao das bolinhas no progabide tambem estao mais concentradas em baixo (mais cor azul).
xyplot(seizure.rate/base ~ period | treatment, group = subject, data = epilepsy, type = "b") # separa por sujeito para associar os sujeitos durante os periodos. A tendencia das linhas tambem parece reduzir (linhas mais compactas)
epilepsy$gretario=cut(epilepsy$age,breaks =c(0,20,30,40,50) ) #vamos pegar na idade e dividmos em niveis/grupo etario. Fazemos o cut com os niveis que definimos
xyplot(seizure.rate/base ~ period | treatment+gretario, group = subject, data = epilepsy, type = "b") #separa todos os periodos por tratamento e grupo etario
plot(x) ou plot(x,type="l") para um gráfico do tipo “índice vs valores de x” ﴾estilo série temporal﴿plot(x,y) para um diagrama de dispersão entre as variáveis numericas x e yplot(f) gera um gráfico de barras para o fator fplot(f,x) gera caixas de bigodes dos valores de x para cada grupo do fator fpar﴿
type="p" ﴾pode ser “l”,“b”,etc, ver ?plot﴿main="Titulo"sub="Subtítulo"xlab="Nome var. x"ylab="Nome var. y"asp=número ﴾relação de escala y/x, aspect ratio﴿ X de 10 em 10 e y de 5 em 5plot(dados$Colesterol,dados$Peso,main="Relação Peso - Colesterol", xlab="Colesterol",ylab="Peso",asp=2)
A é uma data frame então
plot(A) gera uma matriz de diagramas de dispersão entre cada par de variáveis da data frame Aplot(∼ a + b + …, data=A) gera uma matriz de diagramas de dispersão entre as variáveis de A com nome a, b, …plot(a ∼ b + c + …,data=A) gera gráficos de dispersão individualizados entre a variável a e as variáveis b, c, …plot(~ Idade + Altura + Peso + IMC, data=dados)
#Graficos de dispersao entre uma variavel e varias outras de forma individualizada
plot(Idade ~ Peso + IMC, data=dados)
pairs(A)Considerando os dados DQ.RData
#load("DQ.RData")
aux=sapply(dados,is.numeric) # Verificar que vars. são numéricas
plot(dados[,aux]) #plot todas as linhas e apenas variaveis numericas
plot(~ Colesterol+FreqCard+Peso,data=dados)
plot(Colesterol ~ FreqCard+Peso,data=dados)
pairs(dados[,aux])
coplot pode também ser usada para gerar gráficos multivariados, neste caso condicionais; permitem relacionar 3 ou 4 variáveis da seguinte forma ﴾particularmente útil quando c e d são fatores﴿. Semelhantes ao lattice, mas nao pressupoe evoluçao temporal. Aqui é uma so medida
coplot(a∼b| c, data=A) para uma matriz de diagramas de dispersão entre as variáveis a e b para cada grupo do fator c. a em funçao de b condicionada em c. Diagrama de dispersao de a para b por cada grupo do fator ccoplot(a∼b| c+d, data=A) para uma matriz de diagramas de dispersão entre as variáveis a e b para cada combinação de grupos dos fatores c e dcoplot(FreqCard ~ Colesterol|Tabaco,data=dados) # analisar da esquerda para a direita, de baixo para cima (o grafico no topo sozinho corresponde ao fumador) - Fumadores tem freq cariacas mais elevadas e colesterol mais elevado.
coplot(FreqCard ~ Colesterol|Tabaco+Sexo,data=dados)
latticepoints(x,y) para adicionar pontos cujas coordenadas são especificadas por x e ylines(x,y) para adicionar pontos ligados por linhas com coordenadas especificadas por x e ytext(x,y,labels) para adicionar texto contido em labels nas coordenadas (x,y)abline(a,b) para adicionar a reta de equação y = a + bxpolygon(x,y) para adicionar um polígono cujos vértices ordenados estão em (x,y)legend(x,y,legend=leg,col=vetor1,pch=vetor2,lty=vetor3,…) para adicionar uma legenda, onde (x,y) é a posição do canto superior esquerdo, leg é um vetor, tipicamente de caracteres com as etiquetas, vetor1 é um vetor que especifica as cores, vetor2 é um vetor para especificar o símbolo a marcar cada ponto, vetor3 especifica o tipo de linha, etctitle("titulo principal","subtitulo") para adicionar titulo ﴾no topo﴿ e subtítulo ﴾em baixo﴿. Podemos usar expression e paste para concatenar strings, variaveis e notaçao matematica.(x,y) pode ser substituído por locator(n) onde n é o número de inserções a realizar; esta opção permite definir as localizações usando o ratoplot(dados$Colesterol,dados$Peso)
title("Relação Peso - Colesterol")
Col.medio=mean(dados$Colesterol)
Peso.medio=mean(dados$Peso)
points(x=Col.medio,y=Peso.medio,col="blue",pch="+") #fez o ponto medio entre colesterol e peso. Se passasemos uma reta de regressao ela passava por este ponto medio
#text(locator(1),"Sem relação aparente")
x=seq(-5,5,by=0.1)
f1=x^2; f2=exp(x)
plot(x,f1,col="blue",type="l") #plot é uma funçao de alto nivel logo cria um novo grafico sempre que executado. É por isso que usamos o "lines" na proxima linha pois queremos adicionar essa parte do grafico ao grafico pre-existente feito pelo "plot"
lines(x,f2,col="red",type="l")
legend("bottomright",legend=c(expression(paste(x^2)),expression(paste(exp(x)))), col=c("blue","red"),lty=c(1,1)) #lty (line type) define as linhas que vamos definir
Cada graphics device tem os seus defaults que podem ser acedidos com o comando par() ﴾veja‐se ?par﴿
Os parâmetros gráficos pode ser alterados de forma temporária ou de forma permanente
parplot﴿par(bg="darkolivegreen1")
hist(dados$Peso,main="Distribuição de Peso",xlab="Peso", ylab="Frequência",col="aquamarine",border="chocolate1")
plot(dados$Colesterol,dados$Peso)
par(bg="white")
plot(dados$Colesterol,dados$Peso, col=dados$Escolaridade,cex=3,pch="+")
plot(dados$Colesterol,dados$Peso, col=dados$Escolaridade, pch=as.numeric(dados$Tabaco)) #em cada nivel, coloca uma cor diferente. Escolaridade temos diferentes cores e tabaco temos diferentes simbolos. Este "as.numeric" so faz sentido se colocarmos como fator. Se tivessemos as.character teriamos de passar para fator primeiro - pch= as.character(as.factor(c("a","b","c")))
#cor por escolaridade
plot(dados$Colesterol,dados$Peso, col=dados$Escolaridade, pch=as.character(dados$Tabaco)) #neste caso vamos ter diferentes cores para escolaridade e os dados do tabaco vao ser atribuidos a 1ª letra dos fatores
mfrow ou mfcol com a função par(mfrow=c(n,m)); a diferença reside no preenchimento, que no primeiro caso é por linha e no segundo por coluna
par(mfrow=c(1,3))
plot(dados$Colesterol,dados$Peso)
boxplot(Colesterol~Tabaco,data=dados)
hist(dados$Idade)
par(mfrow=c(1,1))
aes() -> o que queremos desenhargeom -> como queremos desenharlibrary(ggplot2)
## Warning: package 'ggplot2' was built under R version 4.0.5
data("iris")
p1 = ggplot(data = iris, aes(x = Petal.Length, y = Petal.Width)) #gera grafico
p1
#Diagrama de dispersao entre as 2 variaveis
p2 = p1 + geom_point()
p2
# Nestes dados as observaçoes correspondem a 1 de 3 especies: iris versicolor, iris virginica ou iris setosa
p3 = p1 +geom_point(aes(color=Species))
p3
p4 = p3 + xlab("Comprimento da petala (cm)") + ylab("largura da petala (cm)") + ggtitle("Comprimento da petala vs largura da petala")
p4
#Alterar o fundo, eixos, etc
a1 = ggplot(data=iris, aes(x=Petal.Length, y = Petal.Width))
a1+theme_classic()
a1+theme_dark()
#install.packages("ggthemes")
library(ggthemes)
## Warning: package 'ggthemes' was built under R version 4.0.5
a1+theme_economist()
a1+theme_excel_new()
a1+theme_solarized()
Usados para analisar frequencias absolutas ou relativas de uma ou mais variaveis qualitativas
Apresentar sumario (media) de uma variavel quantitativa por grupos definidos por uma variavel qualitativa
Funçao usada é geom_bar
library(ggplot2)
#Com frequencias absolutas
#labs permite estabelecer titulos e legendas
ggplot(data=dados, aes(x=Gr_etario))+geom_bar()+labs(x="Grupo etario", y="Frequencia",title="Distribuiçao do grupo etario")
#Com frequencias relativas. geom_bar por defeito faz ..count..; Se fizessemos y = count ia procurar variavel count, mas isso nao existe. Os ".." é uma funçao built in de geom_bar. Se queremos a proporçao fazemos o count pela soma do count (contagem de cada barra a dividir pelo total.)
ggplot(data=dados, aes(x=Gr_etario, y=..count../sum(..count..)))+geom_bar()+labs(x="Grupo etario", y = "Percentagem", title="Distribuiçao do grupo etario")+scale_y_continuous(labels=scales::percent) #scale_y_continous para colocar o eixo do Y como percentagem. Na escala do y queremos que os labels venham em percentagem
#Barras podem ser ordenadas por ordem crescente, decresente e apresentarem uma orientaçao horizontal
tbl=as.data.frame(table(dados$Gr_etario))
names(tbl)[1]="GrupoEtario"
#Tivemos que criar uma contagem dos casos (dataframe) e fazer uma reordenaçao dos valores
ggplot(data=tbl, aes(x=reorder(GrupoEtario,Freq), y=Freq)) + geom_bar(stat="identity")+labs(x="Grupo etario", y="Frequencia", title="Distribuiça do grupo etario")+coord_flip() #alterar os eixos para ficar a horizontal
#reorder vai organizar o grupo etario a partir de um sort pelo valor de frequencia por ordem decrescente. No x vai colocar o grupo etario
#aes(x=reorder(GrupoEtario.sort(Freq.decreasing=T))
#Stat = identity -> contagem ja foi feita pelo table. A estatistica a usar deve ser identity (para usar os valores que estao em data=tbl)
#Depois de fazer coord_flip com barras horizontais, colocavamos Freq.decreasing = F e a barra maior passava para a primeira
#ggplot(data=tbl, aes(x=reorder(GrupoEtario,sort(Freq.decreasing=F)), y=sort(Freq.decreasing=F))) + geom_bar(stat="identity")+labs(x="Grupo etario", y="Frequencia", title="Distribuiça do grupo etario")+coord_flip()
ggplot(data=dados, aes(x=Gr_etario, fill=Tratamento)) + geom_bar(position="stack")
ggplot(data=dados, aes(x=Gr_etario, fill=Tratamento)) + geom_bar(position="dodge")
ggplot(data=dados, aes(x=Gr_etario, fill=Tratamento)) + geom_bar(position="fill") #coloca cada barra para 100% e permite analisar proporçoes
ggplot(dados) + geom_bar(aes(x=Gr_etario, y = PAS), stat="summary", fun="mean") + labs(x="Grupo etario", y="PAS") #para y=PAS queremos fazer um summary em que a funçao a fazer é a media. Eixo do y vai ter o PAS mas com o valor medio. Cada barra representa valor medio
geom_treemap podem ser vistos como uma modificaçao dos graficos de barra, permitindo mais facilmente efetuar uma comparaçao face ao total#install.packages("treemapify")
library(treemapify)
## Warning: package 'treemapify' was built under R version 4.0.5
ggplot(data=tbl, aes(fill=GrupoEtario, area=Freq)) + geom_treemap() + labs(title="Distribuiçao do grupo etario")
tbl
## GrupoEtario Freq
## 1 Ate aos 34 anos 16
## 2 35 - 64 anos 68
## 3 65 e mais anos 16
ggplot(data=tbl, aes(fill=GrupoEtario, area= Freq, label=GrupoEtario))+geom_treemap()+geom_treemap_text(colour="white", place="centre") + labs(title="Distribuiçao do grupo etario") + theme(legend.position = "none")
geom_hist() uteis para distribuiçao de uma amostra relativa a uma variavel quantitativaggplot(data=dados,aes(x=Altura)) + geom_histogram()
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
ggplot(data=dados, aes(x=Altura)) + geom_histogram(fill="dodgerblue", color="black")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
#O numero de barras (sub-intervalos) a construir pode ser redefinido de varias formas (numero, largura ou regra)
ggplot(data=dados, aes(x=Altura)) + geom_histogram(fill="dodgerblue", color="black", bins=20)
ggplot(data=dados, aes(x=Altura)) + geom_histogram(fill="dodgerblue", color="black", binwidth=5)
ggplot(data=dados, aes(x=Altura)) + geom_histogram(fill="dodgerblue", color="black", bins=nclass.Sturges(dados$Altura
))
ggplot(data=dados, aes(x=Altura)) + geom_density()
ggplot(data=dados, aes(x=Altura)) + geom_density(fill="dodgerblue", color="firebrick", size=1)
ggplot(data=dados, aes(x=Altura)) + geom_density(fill="dodgerblue", color="firebrick", size=1, bw=1) #densidade estimada depende do kernel bandwidth, bw. Se bw = 0.1, estimativa esta a ser muito local. Quanto mais alargarmos o bw, mais "smooth" fica
ggplot(data=dados,aes(x=Altura,fill=Gr_etario)) + geom_density(alpha=0.5) #density plot para cada grupo etario
#OU
#install.packages("ggridges")
library(ggridges)
## Warning: package 'ggridges' was built under R version 4.0.5
ggplot(data=dados, aes(x=Altura, y = Gr_etario, fill=Gr_etario)) + geom_density_ridges()
## Picking joint bandwidth of 2.01
Pretende-se analisar a existencia de relaçao entre duas variaveis quantitativas
grafico=ggplot(dados,aes(x = Altura,y = Peso)) + geom_point(color="cornflowerblue",size = 2,alpha=.8) + scale_y_continuous(limits = c(50,90)) + scale_x_continuous(breaks = seq(155, 180, 5), limits=c(155, 180))
grafico + geom_smooth(method="lm")
## `geom_smooth()` using formula 'y ~ x'
grafico + geom_smooth(method = "lm", formula = y ~ poly(x, 2), color = "indianred3")
grafico + geom_smooth(method = "loess", color = "indianred3")
## `geom_smooth()` using formula 'y ~ x'
geom_boxplot podendo-se escolher a orientaçao horizontal ou vertical com coord_flip#orientaçao horizontal
ggplot(data=dados, aes(x=Status)) + geom_boxplot()
#Vertical
ggplot(data=dados, aes(x=Status)) + geom_boxplot()+coord_flip()
ggplot(data=dados, aes(y=Status)) + geom_boxplot()
#
ggplot(data=dados,aes(x=Escolaridade,y=Status)) + geom_boxplot(color="black",fill="cadetblue1", outlier.colour = "red", outlier.shape = 2)
* A opção
notch permite obter uma aproximaçao a um IC a 95% para as medianas e assim efetuar uma comparaçao entre as mesmas (a nao sobreposiçao dos respetivos notches indica diferenças significativas)
ggplot(data=dados,aes(x=Escolaridade,y=Status))+ geom_boxplot(color="black",fill="cadetblue1", outlier.colour = "red", outlier.shape = 2,notch = TRUE) #intervalos de confiança sao sobrepostos, logo nao ha diferença significativa entre medianadas de status entre gurpos etarios
## notch went outside hinges. Try setting notch=FALSE.
ggplot(data=dados,aes(x=Escolaridade,y=Status))+ geom_violin(fill="cornflowerblue")+ geom_boxplot(color="black",fill="cadetblue1", outlier.colour = "red", outlier.shape = 2, width=0.3) #conjugar info de boxplot e density plot, o width controla o tamanho da caixa
psych)#install.packages("psych")
library(psych)
## Warning: package 'psych' was built under R version 4.0.5
##
## Attaching package: 'psych'
## The following objects are masked from 'package:ggplot2':
##
## %+%, alpha
aux=describeBy(dados$PAS,group=dados$Gr_etario,mat = T) #describeBy calcyla sd, media, etc
View(aux) #mat=T passa a formato matriz para ser usado no ggplot
ggplot(aux,aes(x = group1, y = mean,group = 1)) + geom_point(size = 3) + geom_line() + geom_errorbar(aes(ymin=mean-sd,ymax=mean+sd),width = .1) + labs(x="Grupo Etário",y="PAS médio")
# com duas qualitativas
aux=describeBy(dados$PAS,group=list(dados$Gr_etario,dados$Tratamento),mat = T)
ggplot(aux,aes(x = group1, y = mean,group = group2,color=group2)) + geom_point(size = 3) + geom_line() + geom_errorbar(aes(ymin=mean-sd,ymax=mean+sd),width = .1) + labs(x="Grupo Etário",y="PAS médio")
#cruzamento de linhas pode significar que variaveis tem interaçao entre si. PAS pode ter resultados diferentes consoante os niveis das variaveis. Ha interaçao entre os niveis dos grupo etario com os tratamentos e o PAS
#install.packages("ggcorrplot")
library(ggcorrplot)
## Warning: package 'ggcorrplot' was built under R version 4.0.5
dados1=dados[,2:ncol(dados)]
MatCorr=cor(dados1[,sapply(dados1,is.numeric)])
ggcorrplot(MatCorr)
ggcorrplot(MatCorr,hc.order = TRUE,type = "lower",lab = TRUE) #hc.order - clustering das correlaçoes
library(HSAUR3)
data("epilepsy")
ggplot(epilepsy, aes(x = period, y = seizure.rate/base)) + geom_line(aes(color = treatment, group = subject)) + geom_point() #group = subject - da os pontos do grafico
ggplot(epilepsy, aes(x = period, y = seizure.rate/base)) + geom_line(aes(group = subject)) + facet_wrap(~treatment,labeller = label_both) #facet wrap separa por tratamento
ggplot(epilepsy, aes(x = period, y = seizure.rate/base)) + geom_line(aes(color = treatment, group = subject)) + facet_wrap(~subject,labeller=label_both) #linha individualizada, por sujeito
ggplot(epilepsy, aes(x = period, y = seizure.rate/base)) + stat_summary(aes(group = treatment, color = treatment), geom = "line", fun = mean, size = 3) #valores medios das seizure rates de todos do progabide vs todos do placebo
ggplot(epilepsy, aes(x = period, y = seizure.rate/base)) + geom_line(aes(color = treatment, group = subject)) + stat_summary(aes(group = treatment, color = paste("mean", treatment)), geom = "line", fun = mean, size = 3)
dnorm obtém valores da densidade de uma distribuição normal - f minusculopnorm obtém valores de probabilidade acumulada ﴾função distribuição﴿ de uma distribuição normal - F maiusculoqnorm obtém os quantis de uma distribuição normal - damos probabilidade acumulada e retorna o X onde atingimos essa probabilidade (inversa da pnorm)rnorm gera números aleatórios ﴾random﴿ de uma distribuição normaldbinom(x,n,p) - probabilidade de ocorrer X sucessospbinom(x,n,p) - probabilidade acumulada até ao Xqbinom(k,n,p)﴾k é um valor de probabilidade dado﴿rbinom(N,n,p) gera N números aleatórios com distribuição B(n, p)#B(20, 0.5) ﴾gráfico conjunto da amostra e da distribuição exata﴿
p.exato=dbinom(0:20,20,0.5)
x=rbinom(1000,20,0.5)
B=barplot(prop.table(table(factor(x,levels=0:20))))
lines(B,p.exato,type="h",col="blue",lwd=2)
dnorm(x,mu,sigma) ﴾numa distribuição contínua f(x) diz‐se a função densidade e não representa uma probabilidade﴿. dnorm como nao estamos nas discretas, ja nao representa uma probabilidade, mas sim cada um dos pontos.pnorm(x,mu,sigma)qnorm(k,mu,sigma) ﴾k é um valor de probabilidade dado﴿ retorna o ponto até a area acumuladarbinom(N,mu,sigma) gera N números aleatórios com distribuição N(mu, sigma2)x=rnorm(1000,mean=0,sd=1)
y=rnorm(1000,mean=5,sd=2)
hist(x,freq=F) #freq = F, nao vai calcular frequencias. Temos de colocar freq = F pois se tirassemos o Freq, iamos criar um histograma com escala da nossa amostra (0 a 200) e a curva iria ter escala de 0 a 1 (vai estar escondida). Freq = F faz frequencias relativas e depois normaliza os valores para que a soma das barras dê 1
lines(sort(x),dnorm(sort(x),mean=0,sd=1))
hist(y,freq=F)
lines(sort(y),dnorm(sort(y),mean=5,sd=2))
* Os QQ-plots tambem sao uteis para avaliar o ajustamento de uma distribuiçao. Funções
qqnorm e qqline podem ser usadas para analisar a proveniencia de uma dist. normal
x=rnorm(1000,0,1)
qqnorm(x)
qqline(x,col="blue")
y=rchisq(1000,3)
qqnorm(y)
qqline(y,col="red")
Consideremos a estatística T, usada na construção de IC e em TH
N=1000; # número de repetições
media=0
desviop=1
n=10
T=NULL
for (i in 1:N){
x=rnorm(n,media,desviop)
T[i]=(mean(x)-media)/(sd(x)/sqrt(n))
}
#Perceber qual a dist. que tem o T:
qqnorm(T);qqline(T)
shapiro.test(T) #vai ver se t obs esta ou nao na regiao critica. Rejeita a normalidade pois se é uma t student rejeita a normalidade. Temos que usar a distribuiçao correta para confirmar a distribuiçao de T, que neste caso será uma KS .
##
## Shapiro-Wilk normality test
##
## data: T
## W = 0.97988, p-value = 1.571e-10
#NOTA: se aumentarmos muito o n, o shapiro.teste ja vai confirmar a normalidade apesar de ser a distribuiçao errada uma vez que aumentando o n, o T vai tender para a normalidade
#Como rejeitamos com o shapiro.test, vamos agora ajustar cm os graus de liberdade n-1, escolhendo a disribuiçao "pt" (t-student)
ks.test(T,"pt",df=(n-1))
##
## One-sample Kolmogorov-Smirnov test
##
## data: T
## D = 0.033222, p-value = 0.2197
## alternative hypothesis: two-sided
set.seed(3)
N=1000; n=15; media.ex=0
media=NULL;mediaAp=NULL; mediana=NULL
for (i in 1:N){
x=rnorm(n,media.ex,1)
media[i]=mean(x)
mediaAp[i]=mean(x,trim=0.2)
mediana[i]=median(x)
}
resultados=data.frame(media=media, media.aparada=mediaAp, mediana=mediana)
# viés
colMeans(resultados)-media.ex # media dos valores esperados - media exata (Teorica) = vies
## media media.aparada mediana
## -0.011501470 -0.010150869 -0.006407224
# Desvio padrão
sqrt(diag(var(resultados))) #variabilidade de um estimador - o quao diferente o estimador pode ser consoante diferentes amostras. Um sd pequeno significa que por muito que a amostra varie, o estimador vai ser consistente
## media media.aparada mediana
## 0.2563014 0.2695634 0.3080002
# Erro quadrático médio - quanto menor o erro quadratico melhor. É a variancia da diferença
diag(var(resultados-media.ex))
## media media.aparada mediana
## 0.06569039 0.07266444 0.09486415
# Eficiência relativa face ao estimador standard da média (media amostral)
var(resultados$media)/diag(var(resultados)) #mediana seria um estimador menos eficiente face à media tradicional
## media media.aparada mediana
## 1.0000000 0.9040239 0.6924680
#Perante todos os resultados, a media da amostra é o melhor estimador para estimar a media populacional
Exemplo: comparar as médias de uma variável x entre dois grupos de indivíduos dos quais 3 receberam um tratamento e 3 não receberam esse tratamento
library(combinat)
##
## Attaching package: 'combinat'
## The following object is masked from 'package:utils':
##
## combn
set.seed(123)
individuos=letters[1:6]
tratamento=factor(c("Sim","Sim","Sim","Não","Não","Não"),levels = c("Sim","Não"))
x=rnorm(6,mean=c(5,5,5,0,0,0),sd=1) #se alterarmos a meida para 1, vai ser quase indistinguivel pois vao estar sobrepostas. Nesse caso, a diferença ja é irrelevante
dados=data.frame(individuos,tratamento,x)
dados
## individuos tratamento x
## 1 a Sim 4.43952435
## 2 b Sim 4.76982251
## 3 c Sim 6.55870831
## 4 d Não 0.07050839
## 5 e Não 0.12928774
## 6 f Não 1.71506499
aux=by(dados$x,dados$tratamento,mean); aux
## dados$tratamento: Sim
## [1] 5.256018
## ------------------------------------------------------------
## dados$tratamento: Não
## [1] 0.638287
dif.obs=aux[1]-aux[2]
Por inspeção visual ﴾e por construção/simulação do próprio problema﴿ sabemos que existe uma diferença nítida entre as médias dos dois grupos
Uma primeira abordagem seria utilizar um teste de hipóteses para a diferença de médias ﴾teríamos de assumir a Normalidade dos dados﴿ ou um teste não paramétrico
Como nesta abordagem são geradas todas as possíveis permutações da amostra original, é possível calcular a probabilidade exata da diferença observada ﴾na amostra original﴿ ocorrer por acaso
Neste baralhamento, estamos a quebrar as ligaçoes com a amostra original. Faz todas as trocas possiveis e calcula em cada uma delas a media por grupo e faz a diferença.
# Gerar todas as permutações possíveis de tratamento
combin=unique(permn(dados$tratamento)) #todas as permutaçoes para a variavel tratamento - 720 permutaçoes, mas trocar um sim com outro sim da a mesma permutaçao, é por isso que colocamos o unique para ter apenas as diferentes
baralha.tratamento = matrix(unlist(combin), nrow = length(combin), ncol = length(dados$tratamento), byrow = TRUE)
baralha.tratamento
## [,1] [,2] [,3] [,4] [,5] [,6]
## [1,] "Sim" "Sim" "Sim" "Não" "Não" "Não"
## [2,] "Sim" "Sim" "Não" "Sim" "Não" "Não"
## [3,] "Sim" "Não" "Sim" "Sim" "Não" "Não"
## [4,] "Não" "Sim" "Sim" "Sim" "Não" "Não"
## [5,] "Sim" "Sim" "Não" "Não" "Sim" "Não"
## [6,] "Sim" "Não" "Sim" "Não" "Sim" "Não"
## [7,] "Não" "Sim" "Sim" "Não" "Sim" "Não"
## [8,] "Não" "Sim" "Não" "Sim" "Sim" "Não"
## [9,] "Sim" "Não" "Não" "Sim" "Sim" "Não"
## [10,] "Não" "Não" "Sim" "Sim" "Sim" "Não"
## [11,] "Não" "Não" "Sim" "Sim" "Não" "Sim"
## [12,] "Não" "Sim" "Não" "Sim" "Não" "Sim"
## [13,] "Não" "Sim" "Sim" "Não" "Não" "Sim"
## [14,] "Sim" "Não" "Sim" "Não" "Não" "Sim"
## [15,] "Sim" "Não" "Não" "Sim" "Não" "Sim"
## [16,] "Sim" "Sim" "Não" "Não" "Não" "Sim"
## [17,] "Sim" "Não" "Não" "Não" "Sim" "Sim"
## [18,] "Não" "Sim" "Não" "Não" "Sim" "Sim"
## [19,] "Não" "Não" "Sim" "Não" "Sim" "Sim"
## [20,] "Não" "Não" "Não" "Sim" "Sim" "Sim"
# Calcular a diferença de médias para cada combinação
baralha.dif=NULL
for (i in 1:nrow(baralha.tratamento)){ #percorre a matriz
aux=by(dados$x,baralha.tratamento[i,],mean) #pegamos no x e fazemos as medias por grupo (sim e nao) - calculamos a distribuiçao das diferenças ao acaso. Depois vemos onde é que a nossa observaçao inicial (a primeira com sim sim sim nao nao nao), onde é que se localiza na distribuiçao - se ela se posicionar no meio, entao nao é mt diferente do acaso, se ficar nas extermidades, entao esta mt disante do acaso. A diferença que encontramos, estando nas extermidades, é estatisticamente significativa
baralha.dif[i]=aux[1]-aux[2]
}
hist(baralha.dif)
lines(c(dif.obs,dif.obs),c(0,4),col="red")
quantile(baralha.dif,probs = seq(0,1,0.05))
## 0% 5% 10% 15% 20% 25% 30%
## -4.6177314 -2.8922404 -2.6032462 -1.8697882 -1.7128913 -1.5692946 -1.4966111
## 35% 40% 45% 50% 55% 60% 65%
## -1.4223126 -0.7543249 -0.3098985 0.0000000 0.3098985 0.7543249 1.4223126
## 70% 75% 80% 85% 90% 95% 100%
## 1.4966111 1.5692946 1.7128913 1.8697882 2.6032462 2.8922404 4.6177314
tratamento=factor(c(rep("Sim",30),rep("Não",40)), levels = c("Sim","Não"))
x=rnorm(70,mean=c(rep(5,30),rep(0,40)),sd=1)
dados=data.frame(tratamento,x)
aux=by(dados$x,dados$tratamento,mean)
dif.obs=aux[1]-aux[2];dif.obs
## Sim
## 4.952294
reps permutaçoesreps=1000
combin=unique(t(replicate(reps,sample(dados$tratamento,70)))) #vamos aos dados tratamento fazer uma amostragem aleatoria - Em vez de termos sim todos seguidos e nao todos seguidos, vamos ter reamostragem -replicate repete 1000 vezes a amostragem
baralha.dif=NULL
for (i in 1:nrow(combin)){
aux=by(dados$x,combin[i,],mean)
baralha.dif[i]=aux[1]-aux[2]
}
hist(baralha.dif)
lines(c(dif.obs,dif.obs),c(0,100),col="red") #nao aparece porque o valor obs está nos 4 e a escala so vai até 2 - é uma diferença significativa
quantile(baralha.dif,probs = seq(0,1,0.05))
## 0% 5% 10% 15% 20% 25%
## -1.98673863 -0.98688545 -0.76627098 -0.62990576 -0.52213776 -0.41765093
## 30% 35% 40% 45% 50% 55%
## -0.32449068 -0.24499685 -0.17668453 -0.10327525 -0.01961262 0.07284918
## 60% 65% 70% 75% 80% 85%
## 0.14873653 0.22780426 0.30354989 0.40457066 0.47581681 0.61243908
## 90% 95% 100%
## 0.77724018 1.00235838 1.97366720
dif.obs
## Sim
## 4.952294
paises = c("EUA", "Canadá", "México",
"Inglaterra", "França","Espanha", "Alemanha", "Itália",
"China", "Japão","Portugal")
sample(paises, replace = FALSE) #sample faz reamostragem com mesmo tamanho da amostra inicial quando nao colocamos reps, e com replace = F, vai buscar todos os paises por ordem diferente de forma aleatoria
## [1] "França" "México" "China" "Inglaterra" "Canadá"
## [6] "Japão" "Alemanha" "Portugal" "Itália" "EUA"
## [11] "Espanha"
sample(paises, replace = TRUE) #com replace = T, pode ter repetiçoes do mesmo pais
## [1] "Alemanha" "EUA" "França" "Canadá" "Espanha"
## [6] "França" "Inglaterra" "Canadá" "Inglaterra" "Itália"
## [11] "Canadá"
sample(paises, replace = TRUE)
## [1] "Japão" "Espanha" "Portugal" "Japão" "Japão"
## [6] "Espanha" "Inglaterra" "EUA" "China" "Canadá"
## [11] "Portugal"
set.seed(123)
n = 500
N = 1000
amostra = rnorm(n, 4, 5)
media = mean(amostra)
erro.pad = 5/sqrt(n) #sigma / raiz de n
erro.pad.est = sd(amostra)/sqrt(n) #desvio padrao da amostra / raiz de n - podemos ver que o sd da amostra é um estimador do sd populacional pois sao proximos
erro.pad;erro.pad.est
## [1] 0.2236068
## [1] 0.2175178
media.boot = NULL
for (i in 1:N) {
amostra.boot = sample(amostra,size=n,replace = TRUE)
media.boot[i] = mean(amostra.boot)
}
hist(media.boot,main="Distribuição amostral de médias")
sd(media.boot) #erro padrao é o desvio padrao da dist. amostral das medias.
## [1] 0.2151349
# erro padrao da media amostral = sigma / raiz de n (sigma = desvo padrao populaciona) que é aproximado pelo s / raiz de n em que o s é o desvio padrao da amostra original.
# O erro padrao é o desvio padrao da dist. das medias amostrais
#valor obtido é proximo do real (erro.pad e erro.pad.est)
#IC 9% parametrico
media - qnorm(0.975)*sd(media.boot) # Limite inf.
## [1] 3.751295
media + qnorm(0.975)*sd(media.boot) # Limite sup.
## [1] 4.594609
# IC 95% (não-paramétrico) - como temos dist. de medias, vamos ver onde ocorre 2.5 e 97.5% - os valores sao quase iguais com o IC parametrico. O parametrico é mais proximo do teorico pois assume normalidade dos dados. Nesta nao parametrica, baseia-se na replicaçao bootstrap para simular a distribuiçao dos nossos dados originais
quantile(media.boot, .025) # Limite inf.
## 2.5%
## 3.757187
quantile(media.boot, .975) # Limite sup.
## 97.5%
## 4.606669
# Como os dados gerados sao normais, o parametrico e nao parametrico vao dar parecidos, podendo tambem fazer um t.test(amostra) para confirmar os intervalos.
A forma em U para o erro de teste que se pode observar na figura está ligada ao compromisso vies-variancia (bias-variance trade-off)
Por exemplo, prova-se para o caso de modelos de regressao que, para uma dada observaçao de teste x0, se tem: onde t é a variavel a prever e y(x) é o modelo de regressao
Verifica-se que a reduçao do erro quadratico medio de teste deve ser realizada por reduçao simultanea da variancia e do vies do modelo
k-fold cross-validation data("iris")
library(caret)
## Warning: package 'caret' was built under R version 4.0.5
library(class)
## Warning: package 'class' was built under R version 4.0.5
ind=createFolds(iris[,5],k=10,list=TRUE)
# 10-fold CV
erro.cv10=rep(0,10)
for (i in 1:10){
pred=knn(iris[-ind[[i]],-5],iris[ind[[i]],-5],iris[-ind[[i]],5],k=10)
erro.cv10[i]=mean(iris[ind[[i]],5]!=pred)
}
mean(erro.cv10)
## [1] 0.03333333
erro.loocv=rep(0,nrow(iris))
# LOOCV
for (i in 1:nrow(iris)){
pred=knn(iris[-i,-5],iris[i,-5],iris[-i,5],k=10)
erro.loocv[i]=(iris[i,5]!=pred)
}
mean(erro.loocv)
## [1] 0.03333333
set.seed(123)
ind.CV=createFolds(iris$Species,k=10,list=TRUE)
# 10-fold CV ; testar k=1,...,30
erro.k=rep(0,30)
for (k in 1:30){
erro.cv10=rep(0,10)
for (i in 1:10){
pred=knn(iris[-ind.CV[[i]],-5],iris[ind.CV[[i]],-5],
iris[-ind.CV[[i]],5],k=k)
erro.cv10[i]=mean(iris[ind.CV[[i]],5]!=pred)
}
erro.k[k]=mean(erro.cv10)
}
plot(erro.k,type="l",xlab="nº de vizinhos",ylab = "Erro")