teste
#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()
test
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 Sat Nov 06 19:54:57 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 arraysL2=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"
Plot title.
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.138214
## [1] 2.05426
## [1] 0.9329097
## [1] 1.096779
## [1] 1.88324
## [1] 3.770022
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:
table, cumsum e prop.tableload("C:/Users/Rafael Oliveira/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
Plot title.
Para variáveis contínuas começamos por definir as classes e tudo o resto é semelhante
classes=table(cut(dados$PAS,
breaks=nclass.Sturges(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
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
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
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:
tapply(dados$PAS,dados$Gr_etario, mean)
## 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 medianoskewness 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)
cor(dados[,sapply(dados,is.numeric)])
## Processo Idade Peso Altura Status
## Processo 1.0000000000 0.003986777 0.020176241 -0.134530986 0.11228147
## Idade 0.0039867766 1.000000000 0.196734551 0.031443892 -0.03594180
## Peso 0.0201762413 0.196734551 1.000000000 -0.077035353 -0.14372685
## Altura -0.1345309865 0.031443892 -0.077035353 1.000000000 0.08422258
## Status 0.1122814733 -0.035941803 -0.143726848 0.084222583 1.00000000
## VAS -0.6827844399 -0.077752153 0.007113036 0.031982191 -0.10835301
## IMC 0.0985675545 0.128917669 0.815733623 -0.636552781 -0.15633373
## Colesterol -0.0009072887 0.665269935 0.136302466 0.015421234 0.01430456
## PAS -0.0118410865 0.807319333 0.129501679 0.008922137 -0.10011659
## PAD -0.0148900175 0.779541301 0.183050739 0.028076836 -0.12057494
## FreqCard -0.1124110538 -0.048593995 -0.205214227 -0.151067300 -0.11162796
## VAS IMC Colesterol PAS PAD
## Processo -0.682784440 0.098567554 -0.0009072887 -0.011841086 -0.01489002
## Idade -0.077752153 0.128917669 0.6652699346 0.807319333 0.77954130
## Peso 0.007113036 0.815733623 0.1363024657 0.129501679 0.18305074
## Altura 0.031982191 -0.636552781 0.0154212337 0.008922137 0.02807684
## Status -0.108353011 -0.156333735 0.0143045612 -0.100116591 -0.12057494
## VAS 1.000000000 -0.008112323 -0.0503896214 -0.045412003 -0.02613148
## IMC -0.008112323 1.000000000 0.0886982533 0.092772467 0.12227832
## Colesterol -0.050389621 0.088698253 1.0000000000 0.547488950 0.56457617
## PAS -0.045412003 0.092772467 0.5474889501 1.000000000 0.96918268
## PAD -0.026131480 0.122278316 0.5645761738 0.969182684 1.00000000
## FreqCard 0.078670389 -0.080906959 -0.0354214606 -0.050180554 -0.05221153
## FreqCard
## Processo -0.11241105
## Idade -0.04859399
## Peso -0.20521423
## Altura -0.15106730
## Status -0.11162796
## VAS 0.07867039
## IMC -0.08090696
## Colesterol -0.03542146
## PAS -0.05018055
## PAD -0.05221153
## FreqCard 1.00000000
barplot(), geralmente associado ao comando table: barplot(table(x));também com plot(f) onde f é um fatorhist(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
As caixas de bigodes ﴾boxplot﴿ correspondem a uma representação gráfica que dá informação sobre * 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(x,y)plot(dados$PAS,dados$PAD)
Sendo dificil a analise de uma matriz de correlaçao, podemos optar por analise grafica
library(corrplot) dados1=dados[,-1] # Para excluir a variável Processo corrplot(cor(dados1[,sapply(dados1,is.numeric)]))
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
## 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)
xyplot(seizure.rate/base ~ period | treatment, data = epilepsy)
xyplot(seizure.rate/base ~ period | treatment, group = subject, data = epilepsy, type = "b")
epilepsy$gretario=cut(epilepsy$age,breaks =c(0,20,30,40,50) )
xyplot(seizure.rate/base ~ period | treatment+gretario, group = subject, data = epilepsy, type = "b")
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 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﴿plot(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, …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(~ 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﴿
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 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 d coplot(FreqCard ~ Colesterol|Tabaco,data=dados) 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)