Parte I: Conceitos Básicos de Programação no R

Objetos e Classes

Toda variável dentro da linguagem R é interpretada como um objeto que pertence a uma determinada classe. Para saber qual a classe de um certo objeto podemos usar a função class(). Veja alguns exemplos.

a = 4
class(a)
## [1] "numeric"
class("abc")
## [1] "character"

Existem diversos tipos de classes. Algumas serão vistas ao longo deste curso e outras apenas em disciplinas futuras. Podemos citar alguns tipos básicos que serão vistos na aula de hoje: "numeric", "logical", "character", "matrix" e "list".

Números

Os objetos numéricos fazem parte da classe "numeric" e tratam-se dos números reais. Para criar um objeto desse tipo podemos usar, por exemplo, o comando x<-3.4 ou x = 3.4 (que são a mesma coisa). Para verificar a sua classe basta usar a função class():

x = 3.4
class(x)
## [1] "numeric"

Para os objetos desse tipo já estão definidos alguns operadores (+, -, *, /, ^) além de funções conhecidas, como por exemplo sqrt(), log(), exp(), abs(), entre outras.

a = 2 + 2; b = 3*a
a; b
## [1] 4
## [1] 12
sqrt(a)
## [1] 2
exp(a - 3)
## [1] 2.718282
log(b/12)
## [1] 0
abs(-b^2)
## [1] 144

Para saber mais detalhes sobre essas funções ou sobre a classe "numeric" use o comando help do R.

help(log)
help("numeric")

Textos

Os objetos do tipo textos fazem parte da classe "character" e são dessa forma que o R guarda letras ou frases. Dentro do R os textos sempre vão aparecer entre aspas. Para criar um objeto desse tipo podemos usar, por exemplo,

ch1<-"a";ch2<-"abc";ch3<-"1"
class(ch1);class(ch2);class(ch3)
## [1] "character"
## [1] "character"
## [1] "character"

Veja que ch3 não é um número e sim um texto, ou seja, é o número 1 armazenado como texto.

Uma função muito usada com objetos da classe "character" é a função paste(). Ela recebe como argumento de entrada objetos do tipo "character" e retorna um único objeto, também do tipo "character", que é definido pela concatenação dos objetos passados como entrada. Quando chamamos o comando paste() podemos indicar como os objetos serão separados na concatenação usando o argumento de entrada sep. Se este argumento não for definido ele sera considerado como espaço.

paste("a","b","c")
## [1] "a b c"
paste("a","b","c",sep=",")
## [1] "a,b,c"
paste("a","b","c",sep="")
## [1] "abc"
ch4 <- paste(ch1,ch2,"a",sep=".")
ch4
## [1] "a.abc.a"
class(ch4)
## [1] "character"

Para saber mais sobre a classe "character" consulte o help do R através do comando help(character).

Lógicos

Os objetos do tipo lógicos fazem parte da classe "logical" e podem ser de dois tipos: TRUE ou FALSE. Eles também podem ser simplesmente representados pelas letras T ou F.

v<-TRUE
b<-T
class(v)
## [1] "logical"
class(b)
## [1] "logical"
v
## [1] TRUE
b
## [1] TRUE

Dentro do R já estão definidos os operadores lógicos E (\(\cap\)) e OU (\(\cup\)). Estes são aplicados a partir dos comandos &&, &, || e |. A tabela verdade a seguir indica a resposta para cada um desses dois operadores.

A B A&&B A||B
TRUE TRUE TRUE TRUE
TRUE FALSE FALSE TRUE
FALSE TRUE FALSE TRUE
FALSE FALSE FALSE FALSE

Vejamos alguns exemplos,

A = TRUE; B = FALSE
A&&B; A&B
## [1] FALSE
## [1] FALSE
A||B; A|B
## [1] TRUE
## [1] TRUE

Também podemos realizar a negação desses objetos usando o comando !.

NegA = !A; NegA 
## [1] FALSE
NegB = !B; NegB
## [1] TRUE

Se quisermos testar se dois objetos são iguais ou diferentes, podemos usar os comandos == ou !=. A resposta será um objeto da classe "logical": TRUE se os objetos fore iguais e FALSEse forem diferentes.

a<-1; b<-1; c<-2; d<-"2"
a==b
## [1] TRUE
a==c
## [1] FALSE
c==d
## [1] TRUE

Repare que no último comando ele respondeu "TRUE" mesmo os objetos sendo de classes diferentes. O programa provavelmente converte todos para a mesma classe antes de testar se são iguais.

a!=b
## [1] FALSE
b!=c
## [1] TRUE
c!=d
## [1] FALSE

Podemos ainda usar os operadores + e * com objetos do tipo "logical". Nesse caso o objeto igual a TRUE é interpretado como o número 1 e o objeto FALSE como 0.

V_1 = TRUE
V_2 = TRUE
F_1 = FALSE
F_2 = FALSE
V_1 + V_2
## [1] 2
V_1 + F_1
## [1] 1
F_1 * V_2
## [1] 0
V_1 * V_2
## [1] 1

Para saber mais sobre a classe "logical" consulte o help do R através do comando help(logical)

Array

Antes de falarmos dos dois últimos tipos de objetos dessa aula vamos parar para entender um conceito importante em qualquer linguagem de programação, o conceito de array.

Em programação de computadores, um array (ou vetor) é uma estrutura de dados que armazena uma coleção de elementos de tal forma que cada um dos elementos pode ser identificado por um índice. No R podemos entender como uma coleção de objetos, sendo todos de um mesmo tipo, obrigatoriamente.

Por exemplo, podemos ter um array de números reais (coleção de objetos do tipo "numeric"), um array de textos (coleçãode objetos do tipo "character"), um array de “verdadeiro” ou “falso” (coleção de objetos do tipo "logical"), ou um array de objetos de qualquer outra classe do R.

No R existem várias maneiras de criarmos um array, a mais simples delas é usando a função c(), que combina objetos formando um array.

a<-c(1,2,3);a
## [1] 1 2 3
b<-c("a", "aa");b
## [1] "a"  "aa"
c<-c(T,T,F,F);c
## [1]  TRUE  TRUE FALSE FALSE

No R, array não é uma classe. Os objetos a, b e c são, respectivamente, das classes "numeric", "character" e "logical". Isso ocorre pois o R trata qualquer objeto como um array. No caso de ser um objeto simples, e não uma coleção de objetos, o R interpreta como se fosse um array de tamanho 1.

Uma função muito usada em arrays é a função length(), que retorna o tamanho do array.

length(a); length(b); length(c)
## [1] 3
## [1] 2
## [1] 4

Para acessarmos uma posição de um array usamos ocolchetes ([]). Por exemplo,

a[1]
## [1] 1
b[2]
## [1] "aa"
c[3]
## [1] FALSE

Se acessarmos uma posição que não tenha sido definida a resposta será NA, que representa o termo em inglês “Not Available”.

a[5]
## [1] NA

Existem outras maneiras de criarmos arrays dentro do R. Uma delas é usando o próprio colchetes ([ ]) para alocarmos uma posição específica.

d = 1
d
## [1] 1
d[2] = 3
d[4] = 5
d
## [1]  1  3 NA  5
d[4] = 7
d[3] = 5
d
## [1] 1 3 5 7

No exemplo acima o objeto d foi iniciado como um array de tamanho 1 da classe numeric. Temos também a possibilidade de iniciar um objeto como vazio, ou nulo.

e = NULL
e
## NULL
e[2] = 4
e
## [1] NA  4
e[1] = 2
e
## [1] 2 4

A função c() serve não só para concatenar objetos em um array, como também ela pode ser usada para concatenar um array com um novo objeto ou concatenar vários arrays. Lembrando que em um mesmo array todos os objetos são sempre da mesma classe.

a
## [1] 1 2 3
c(a,4)    #colocando um elemento no final do array a
## [1] 1 2 3 4
c(0,a)    #colocando um elemento no inicio do array a
## [1] 0 1 2 3
a = c(0,a,4)
e
## [1] 2 4
c(a,e)    #concatenando dois arrays
## [1] 0 1 2 3 4 2 4
b
## [1] "a"  "aa"
c(a,b)    #concatenando arrays de classes diferentes, uma das classes eh transformada na outra
## [1] "0"  "1"  "2"  "3"  "4"  "a"  "aa"

Temos ainda outras maneiras de criarmos arrays dentro do R, vejamos mais alguns exemplos.

1:10
##  [1]  1  2  3  4  5  6  7  8  9 10
seq(1,20,by=2)
##  [1]  1  3  5  7  9 11 13 15 17 19
rep(0,times=4)
## [1] 0 0 0 0

Uma última maneira de se iniciar um array quando já se sabe o tipo, mas ainda não sabemos os elementos:

v1 = numeric(2)
v1
## [1] 0 0
v2 = character(5)
v2
## [1] "" "" "" "" ""
v3 = logical(4)
v3
## [1] FALSE FALSE FALSE FALSE

Antes de seguir para a próxima seção, veja que ainda é possível usar os operadores e funções das classes em uma array de tamanho maior que 1. Os operadores e funções acabam sendo aplicados a cada posição do array e retornam um array como resposta.

Veja primeiro alguns exemplos na classe "numeric".

a = seq(1:10)
b = rep(2,10)
a;b
##  [1]  1  2  3  4  5  6  7  8  9 10
##  [1] 2 2 2 2 2 2 2 2 2 2
a + b
##  [1]  3  4  5  6  7  8  9 10 11 12
a - b
##  [1] -1  0  1  2  3  4  5  6  7  8
a * b
##  [1]  2  4  6  8 10 12 14 16 18 20
a / b
##  [1] 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0
exp(a)
##  [1]     2.718282     7.389056    20.085537    54.598150   148.413159
##  [6]   403.428793  1096.633158  2980.957987  8103.083928 22026.465795

Veja mais alguns exemplos em outras classes.

a = c("a","aa","aaa")
b = c("b","bb","bbb")
paste(a,b)
## [1] "a b"     "aa bb"   "aaa bbb"
a1 = c("a","a","a")
a==a1
## [1]  TRUE FALSE FALSE

Matrizes

Dentro da linguagem R existe uma classe chamada "matrix" que guarda objetos do mesmo tipo em forma de matriz, ou seja, guarda os objetos por linhas e colunas. Mesmo sendo uma estrutura de dados onde cada objeto pode ser identificado por um par de índices, como no caso do array, diferente do array as matrizes são uma classe no R.

Para criar um novo objeto do tipo "matrix" podemos usar a função matrix(data=, nrow=, ncol=, byrow=, dimnames=). Ao lado do sinal de = devemos colocar as informações da matriz que está sendo criada:

Nome Descrição
data array com os objetos que serão alocado dentro da matriz
ncol número de colunas da matriz
nrow número de linhas da matriz
byrow TRUE ou FALSE, que indica se os objetos serão alocados por linha (TRUE) ou por coluna (FALSE)
dimnames uma lista com os nomes para as linhas e colunas da matriz

Se alguma das informações não for preenchida será considerado o valor padrão para cada entrada, que nesse caso são:

data=NA, ncol=1, nrow=1, byrow = FALSE e dimnames = NULL.

Vejamos alguns exemplos de como criar matrizes no R.

m1 <- matrix(c(1,2,3,11,12,13), nrow = 2, ncol=3, byrow=TRUE)
m1
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]   11   12   13
class(m1)
## [1] "matrix"

Veja que se mudarmos o número de linhas ou colunas a matriz criada fica totalmente diferente.

m2 <- matrix(c(1,2,3,11,12,13), nrow = 3, ncol=2, byrow=TRUE)
m2
##      [,1] [,2]
## [1,]    1    2
## [2,]    3   11
## [3,]   12   13

Veja agora como ficaria a matriz se ela fosse alocada por colunas (byrow=FALSE).

m3 <- matrix(c(1,2,3,11,12,13), nrow = 3, ncol=2, byrow=FALSE)
m3
##      [,1] [,2]
## [1,]    1   11
## [2,]    2   12
## [3,]    3   13

Quando criamos um objeto da classe "matrix", o número de linhas e de colunas tem que ser determinado logo de início e não pode ser alterado depois.

Os elementos de uma matriz são acessados usando colchetes ([ , ]), mas diferente do array, aqui temos que informar o índice da linha e da coluna que querermos acessar, separados por vírgula.

m3[2,1]
## [1] 2

Podemos usar os colchetes ainda para acessar uma linha inteira ou coluna inteira da matriz. Nesse caso o objeto retornado será uma array dos objetos da linha ou coluna da matriz.

m3[1,]
## [1]  1 11
m3[,2]
## [1] 11 12 13

Se quisermos o número de linhas de uma matriz podemos usar a função nrow() e se quisermos o número de colunas usamos a função ncol().

nrow(m3)
## [1] 3
ncol(m3)
## [1] 2

Para saber mais sobre a classe "matrix" consulte o help do R através do comando help(matrix).

Listas

Na linguagem R a classe que guarda os objetos em forma de uma lista é denominada "list". Um objeto da classe "list" se diferencia dos arrays principalmetne pelo fato de poder guardar objetos de tipos diferentes. Além disso, as listas definem uma classe, e os arrays não.

Para criarmos uma lista vamos usar a função list().

l1 <- list()
l1
## list()

o objeto l1 criado acima representa uma lista vazia. Se dentro dos parênteses colocarmos uma sequencia de objetos, a lista criada será composta por tais objetos.

l2 <- list(1,"a",TRUE)
l2
## [[1]]
## [1] 1
## 
## [[2]]
## [1] "a"
## 
## [[3]]
## [1] TRUE
class(l2)
## [1] "list"
l3 <- list(c(1,2,3),c(1,1,1,1),TRUE,c("A","a"))
l3
## [[1]]
## [1] 1 2 3
## 
## [[2]]
## [1] 1 1 1 1
## 
## [[3]]
## [1] TRUE
## 
## [[4]]
## [1] "A" "a"

Podemos até criar uma lista de listas, por exemplo:

l4 <- list(l1,l2,l3)

Enquanto usamos colchetes simples ([ ]) para acessar uma posição de um array, para acessar as posições de uma lista usaremos colchetes duplo [[ ]].

l3[[2]]
## [1] 1 1 1 1
l3[[1]][2]
## [1] 2

Para saber o tamanho de uma lista também podemos usar o comando length().

length(l1)
## [1] 0
length(l2)
## [1] 3
length(l3)
## [1] 4
length(l4)
## [1] 3

Pergunta: Se digitarmos length(l3[[2]]), qual a resposta retornada?

length(l3[[2]])
## [1] 4

Da mesma forma que os arrays, novas posições de uma lista podem ser alocadas após a criação do objeto. No caso das listas usaremos o colchete duplo pra isso ([[ ]]). Além de alocar novas posições ele também serve para modificar posições já existentes.

l2
## [[1]]
## [1] 1
## 
## [[2]]
## [1] "a"
## 
## [[3]]
## [1] TRUE
l2[[4]]<-c(1,2,3)
l2
## [[1]]
## [1] 1
## 
## [[2]]
## [1] "a"
## 
## [[3]]
## [1] TRUE
## 
## [[4]]
## [1] 1 2 3

Para saber mais sobre a classe "list" consulte o help do R através do comando help(list).