Descrições legais

Material adaptado do Apêndice A do livro: “Uma Breve Introdução à Mineração de Dados: Bases Para a Ciência de Dados, com Exemplos em R.” por Joaquim V. C. Assunção.

Contato: joaquim@inf.ufsm.br

Origem

R é uma variante da linguagem S. Foi criada em 1991 por Ross Ihaka e por Robert Gentleman no departamento de Estatística da universidade de Auckland, Nova Zelândia. Foi desenvolvido em um esforço colaborativo de pessoas em vários locais do mundo. Foi exposta ao público em 93.

Usada principalmente por estatísticos, matemáticos e cientístas de dados. R

Brevíssimo Histórico do R

Segundo o site www.r-project.org: “R é um conjunto integrado de instalações de software para manipulação de dados, cálculo e exibição gráfica”; que inclui:

  • uma instalação eficaz de tratamento e armazenamento de dados;
  • um conjunto de operadores para cálculos em matrizes;
  • uma grande coleção coerente e integrada de ferramentas intermediárias para análise de dados;
  • instalações gráficas para análise de dados e exibição na tela;
  • uma linguagem de programação bem desenvolvida, simples e eficaz, que inclui condicionais, loops, funções recursivas definidas pelo usuário e instalações de entrada e saída.

Usando o R

  • Você pode digitar os comandos diretamente no console (janela de comandos), ou criar um script com o código.

  • Usamos print(<var>) para imprimir uma variável. Isto é, fazer uma saída na tela correspondente ao valor da variável em questão. No console, a chamada print(<var>) acontece implicitamente.

> x <- 1
> print(x)
[1] 1
> x
[1] 1
> x <- x+1
[1] 2
> msg <- "Oi"

Usando o R

  • O caractere # indica um comentário. Tudo a direita de # será tratado como um texto qualquer.

  • Quando uma expressão completa é adicionada no prompt, esta é avaliada e o resultado da expressão é retornado. Isso pode ocorrer automaticamente.

  • Colchetes ([n]) na impressão indicam que a variável é um vetor e que o elemento, mostrado na linha, é do índice n. No seguinte exemplo, [1] indica que x é um vetor, e 5 é seu primeiro elemento.

> x <- 5  # Nada será impresso
> x       # x é impresso automaticamente
[1] 5
> print(x)  # x é explicitamente impresso
[1] 5

Tipos primitivos de dados

R tem cinco objetos ou classes “atômicas”:

1 - character
2 - numeric
3 - integer
4 - complex
5 - logical

character

Zero ou mais caracteres criados entre aspas. Note que, diferentemente de outras linguagens de programação, uma string em R é um aglomerado (não vetor) de caracteres chamado de character. Isto implica que o índice 1 retorna toda a string, e não o primeiro caractere. A função class() retorna a classe (o tipo) do objeto.

> foo <- 'Isto é uma classe character, acredite'
> class(foo)
[1] "character"
> nada <- ''
> class(nada)
[1] "character"
> foo[1]
[1] "Isto é uma classe character, acredite"

numeric (números reais)

Mais conhecido como double ou float, tipos numéricos são tipos de dados que possuem representação pós-vírgula. Real ou decimal também são semelhantes que podem ser encontrados (exemplo: tipos de dados do MySQL). No R, o tipo numérico com duas casas pós-vírgula de precisão é o padrão. Por exemplo, idade <- 20 gera a variável idade que será do tipo numeric.

> valor <- 99.99
> class(valor)
[1] "numeric"
> valorAcao <- 20.99999
> valorAcao
[1] 20.99999
> idade <- 20
> class(idade)
[1] "numeric"

integer

Um número inteiro positivo ou negativo. Não possuem representação pós-vírgula. Para explicitamente solicitar um inteiro, o sufixo L se faz necessário. Como alternativa, podemos chamar a função integer().

> idade <- integer(20)
> class(idade)
[1] "integer"

integer

Exemplo: A entrada 1 gera um objeto numérico com precisão decimal (numeric); a entrada 1L explicitamente gera um inteiro.

> class(1L)
[1] "integer"

Se quisermos converter um numeric para inteiro, poderemos usar round(), trunc() ou ceiling(). Observe os exemplos abaixo.

> valorAcao <- 15.59
> round(valorAcao)  #Valor inteiro mais próximo
[1] 16
> trunc(valorAcao)  #Valor inteiro sem a precisão decimal
[1] 15
> ceiling(valorAcao)  #Valor inteiro imediatamente superior
[1] 16

integer

Há um número especial Inf que representa o infinito (isto também vale para tipos numéricos). Exemplos:

> 1/0
[1] Inf

O resultado Inf pode ser usado para cálculos quaisquer. Por exemplo:

> 1/Inf
[1] 0

Caso o número seja indefinido, teremos o valor NaN (“not a number”).

complex

Um número puramente imaginário. No exemplo abaixo, se não soubermos o que é i e não atribuirmos nenhuma operação a ele, z será um número complexo.

> z = 1 + 2i
> class(z)
[1] "complex"

logical

Variável que guarda verdadeiro (TRUE) ou falso (FALSE) como resultado de uma expressão lógica.

> a <- 1; b <- 2
> x <- a > b
> class(x)
[1] "logical"
> x
[1] FALSE

logical

Os valores 1 e 0 podem ser usados como representantes para, respectivamente, verdadeiro e falso. Por exemplo, usando a variável x do código acima, temos:

> x == 0
[1] TRUE
> x == 1
[1] FALSE

Vetores

Saindo das classes atômicas, temos os objetos. Em R, o objeto mais básico é um vetor.

Vetores

  • Um vetor não pode ser formado por classes diferentes (a lista é uma exceção, foi criada para isso).
  • Vetores vazios podem ser criados com a função vector() ou simplesmente adicionando conjuntos de dados a uma variável.
  • Note que a chamada class irá retornar o tipo primitivo contido no vetor.
  • A função c() pode ser usada para criar vetores de objetos.
> x <- c(0.5, 0.6)       ## Numérico
> x <- c(TRUE, FALSE)    ## lógico
> x <- c(T, F)           ## lógico
> x <- c("a", "b", "c")  ## caractere
> x <- 9:29              ## inteiro
> x <- c(1+0i, 2+4i)     ## complexo

Vetores

> primos <- c(2,3,5,7,11)
> primos
[1]  2  3  5  7 11
> class(primos)
[1] "numeric"

> chuvaSol <- c(TRUE, FALSE, TRUE, FALSE, TRUE)
> class(chuvaSol)
[1] "logical"

Vetores

…Também podemos usar a função vector()

> x <- vector("numeric", length = 10) 
> x
 [1] 0 0 0 0 0 0 0 0 0 0

Ao contrário da maioria das linguagens de programação, em R, vetores iniciam no índice 1. Veja o código abaixo (o segundo número primo é 3).

> primos[2]
[1] 3

Vetores

Também podemos solicitar uma consulta pela exclusão de um índice. Todos os números primos armazenados, menos o segundo.

> primos[-2]
[1]  2  5  7 11

Operações lógicas ou aritméticas também pode ser aplicada para vetores inteiros, sem a necessidade de laços de repetição.

> primos*2
[1]  4  6 10 14 22
> primos*primos
[1]   4   9  25  49 121
> primos+1
[1]  3  4  6  8 12

Vetores

Algumas combinações são permitidas e, possivelmente, resultam em saídas não tão óbvias. Exemplo: o que acontece se somarmos o vetor numérico primos com o vetor lógico chuvaSol?

primos+chuvaSol

Vetores

Os índices que sofreram incremento de 1 são os índices cujos elementos do vetor chuvaSol são verdadeiros. Isso acontece porque o R entende, mesmo em operações aritméticas, verdadeiro como 1 e falso como 0.

Finalmente, podemos combinar vetores.

> primosclima <- c(primos,chuvaSol)
> primosclima
 [1]  2  3  5  7 11  1  0  1  0  1

Vetores

> vetor_estranho <- c(1.7, "a")   ## caractere
> vetor_estranho <- c(TRUE, 2)    ## numérico
> vetor_estranho <- c("a", TRUE)  ## caractere

Quando diferentes objetos são postos em um vetor, acontece a coerção e o vetor continua com um só tipo. Podemos fazer coerções explícitas, ou seja, objetos serão compelidos a uma outra classe via função as.* (caso esteja disponível).

Vetores

Quando diferentes objetos são postos em um vetor, acontece a coerção e o vetor continua com um só tipo. Podemos fazer coerções explícitas, ou seja, objetos serão compelidos a uma outra classe via função as.* (caso esteja disponível).

Quais as saídas geradas pelos seguintes trechos de código?

> zeroanove <- 0:9 # Qual a classe?
> foo <- as.numeric(zeroanove)
> class(foo)
[1] "numeric"
> foo <- as.logical(zeroanove)
> class(foo)
[1] "logical"
> foo
 ?
> as.character(zeroanove)
 ?

Estruturas de seleção e repetição

Qualquer linguagem de programação/script que se preze tem um conjunto de estruturas comuns de seleção e repetição. Eis um breve resumo dessas estruturas em R.

IF ( … )

Se( -condição-)então

a <- 5
b <- 4
> a <- 5
> b <- 4
> if(a == b){ 
+     print(a)
+ }else{ print(b) }
[1] 4

WHILE( … )

enquanto(-condição-)faça

> while(i > 1){ 
+     print(i)
+     i <- i-3
+ }
[1] 9
[1] 6
[1] 3

FOR( … )

para(-var- em -alcance-)faça

> for (i in 1:3){
+     print(i*2)
+ }
[1] 2
[1] 4
[1] 6

Perceba que o segundo parâmetro do laço é um vetor. Este pode ser criado por uma sequência (como no exemplo 1:3), atribuido por uma variável (vetor), ou extraído de outros objetos que gerem um vetor (por exemplo, uma matriz ou um data frame).

Matrizes e Data Frames

Matrizes são coleções de dados organizadas em uma tabela de \(m\) linhas e \(n\) colunas. No R, matrizes possuem um atributo dimension que por si é um vetor de inteiros com tamanho 2 (\(m\) e \(n\)), indicando número de linhas e número de colunas (nrow, ncol).

Matrizes e Data Frames

No R, tendo as dimensões definidas, precisamos de uma linha de código.

> m <- 2
> n <- 3
> A <- matrix(nrow = m, ncol = n) 
> A
     [,1] [,2] [,3]
[1,]   NA   NA   NA
[2,]   NA   NA   NA

Matrizes

A função dim() pode ser usada para verificar a dimensão de uma matriz.

> dim(A)
[1] 2 3
> attributes(A)
$dim
[1] 2 3

Matrizes

Matrizes são construídas variando mais rapidamente o índice de suas linhas, use o parâmetro byrow=TRUE para alterar a ordem. Os parâmetros passados são, respectivamente, vetor de dados, número de linhas (nrow) e número de colunas (ncol).

> A <- matrix(1:6, nrow = 2, ncol = 3) 
> A <- matrix(1:6, nrow = 2, ncol = 3, byrow = TRUE)

Do it!
- Verifique a matriz A para cada um dos códigos acima.

Matrizes

Matrizes também podem ser criadas diretamente de vetores por meio da transformação do atributo dim (dimensões).

> A <- 1:10 
> A
[1] 1 2 3 4 5 6 7 8 9 10 
> dim(A) <- c(2, 5)

Do it!
- Verifique a matriz A.

Matrizes

Matrizes podem ser criadas via column-binding ou row-binding com cbind() e rbind().

> x <- 1:3
> y <- 10:12
> cbind(x, y)

> A <- rbind(x, y) 

Do it!
- Verifique as saídas.

Matrizes

Podemos resgatar um elemento de uma matrix pelos seus índices.

> A[2,3]    # Elemento na segunda linha e na terceira coluna.
 y 
12 

Data frame

Data frames são usados para armazenar dados estruturados de maneira tabular. Imagine um dataframe como uma matriz com propriedades extras como, por exemplo, nome das linhas e colunas.

Data frame

Comumente, você usará arquivos .csv para armazenar dados. Carregar arquivos .csv (via função read.csv()) gera um objeto data.frame. Use head(X,n) para ver as primeiras n linhas de um data frame X.

> X <- read.csv(url("http://www-usr.inf.ufsm.br/~joaquim/book_datasets/
                      classificacao_ex_GoT.csv"))
> head(X,2)
  Pessoa   Cabelo Peso Altura Genero
1 Tyrion    Curto   45    130      M
2   John Comprido   65    170      M
> class(X)
[1] "data.frame"

Data frame

As seguintes características são válidas para esta classe:

  • Pode ser considerada um tipo especial de lista (cada elemento possui o mesmo tamanho).

  • Também pode ser considerada como um tipo especial de matriz, onde cada coluna pode conter diferentes classes, e linhas e colunas podem conter rótulos (atributo names para colunas, e row.names para linhas).

  • As funções read.table() ou read.csv() geralmente são usadas para carregar arquivos para um data frame.

  • Pode ser convertida para matrizes por meio da chamada data.matrix().

  • Pode-se obter um data frame diretamente de uma matriz com data.frame().

Data frame

> X <- data.frame(foo = 1:4, bar = c(T, T, F, F)) 
> X

> nrow(X)

> ncol(X)

> A <- matrix(1:6, nrow = 2, ncol = 3, byrow=TRUE)
> A

> data.frame(A)

Do it!
- Verifique as saídas.

Data frame

Uma coluna pode ser acessada usando o operador $ ou o segundo elemento nos colchetes [intParaLinha, intParaColuna].

> X$Peso
 [1]  45  65 100  55 110  70  80  58  65  56
> X[2,3]
[1] 65

Data frame

Em complemento às estruturas comuns de repetição, R conta com funções apply(), especialmente úteis para matrizes ou data frames. Observe o código abaixo, com uma estrutura de repetição comum, usaríamos dois laços encadeados para fazer a média das colunas. O mesmo resultado pode ser obtido com sapply() (apply “simplificado”), mas com performance superior.

> X <- read.csv(url("http://www-usr.inf.ufsm.br/~joaquim/book_datasets/
                  classificacao_ex_GoT.csv"))
> head(X,2)
  Pessoa   Cabelo Peso Altura Genero
1 Tyrion    Curto   45    130      M
2   John Comprido   65    170      M
> sapply(X[,3:4],mean)
  Peso Altura 
  70.4  169.9 

Listas e Factors

Uma lista é um tipo especial de vetor que contêm elementos de diferentes classes. Considere a lista como um vetor genérico que suporta outros tipos de elementos.

Listas e Factors

Exemplos:

> primos <- c(2,3,5,7,11)
> primos
[1]  2  3  5  7 11
> alphabeta <- c("a","b","c","d")
> chuva <- c(TRUE, FALSE, TRUE, FALSE, TRUE)
> X <- list(primos, alphabeta, chuva); X
[[1]]
[1]  2  3  5  7 11

[[2]]
[1] "a" "b" "c" "d"

[[3]]
[1]  TRUE FALSE  TRUE FALSE  TRUE
> class(X)
[1] "list"

Factors

Factors são usados para representar dados categóricos. Factors podem ser ordenados ou não. Pense em um factor de inteiros como um vetor (de inteiros), onde cada elemento possui um label (rótulo).

  • Factors são tratados especialmente por funções de modelagem como lm() e glm().

  • Factors são autodescritivos, isso deixa as coisas mais claras em certos casos; é melhor ter uma variável “Masculino” e “Feminino” do que apenas valores representantes (exemplo: 1,2).

Factors

Exemplos:

> X <- factor(c("yes", "yes", "no", "yes", "no")) 
> X
[1] yes yes no yes no
Levels: no yes
> table(X) 
X
no yes 
 2   3
> unclass(X)
[1] 2 2 1 2 1
attr(,"levels")
[1] "no"  "yes"

Factors

Alguns pacotes não entendem vetores binários diretamente, é necessária a conversão para factor.

> X <- data.frame(foo = 1:4, bar = c(T, T, F, F)) 
> X
  foo   bar
1   1  TRUE
2   2  TRUE
3   3 FALSE
4   4 FALSE
> X$bar
[1]  TRUE  TRUE FALSE FALSE
> as.factor(X$bar)
[1] TRUE  TRUE  FALSE FALSE
Levels: FALSE TRUE

Factors

A ordem dos níveis pode ser ajustada pelo argumento levels de factor(). Isso pode ser importante para modelos em que o primeiro nível é usado como base.

> X <- factor(c("yes", "yes", "no", "yes", "no"),
              levels = c("yes", "no"))
> X
[1] yes yes no yes no 
Levels: yes no

Valores faltantes e nomes

Valores faltantes são descritos por NA (Not Available) ou NaN (Not a Number) para operações matemáticas não definidas.

Valores faltantes e nomes

  • is.na() é usado para testar se objetos são NA.

  • is.nan() é usado para testar NaN.

  • Valores NA também possuem classe, inteiro NA, caractere NA, etc.

  • Um valor NaN é também um NA, mas o inverso não se aplica.

Valores faltantes e nomes

Exemplos:

> x <- c(9, 2, NA, 9, 3, 4)
> is.na(x)
[1] FALSE FALSE  TRUE FALSE FALSE FALSE
> is.nan(x)
[1] FALSE FALSE FALSE FALSE FALSE FALSE
> x <- c(1, 2, NaN, NA, 4)
> is.na(x)
[1] FALSE FALSE  TRUE  TRUE FALSE
> is.nan(x)
[1] FALSE FALSE  TRUE FALSE FALSE

Valores faltantes e nomes

Vetores em R podem ter nomes.

> x <- 1:3
> names(x)
NULL
> names(x) <- c("foo", "bar", "norf") 
> x
foo bar norf 
  1   2    3
> names(x)
[1] "foo"  "bar"  "norf"

Valores faltantes e nomes

Assim como listas e outros objetos.

> x <- list(a = 1, b = 2, c = 3) 
> x
$a
[1] 1

$b 
[1] 2

$c 
[1] 3

Pacotes

Pacotes

R contém centenas de pacotes (ou bibliotecas) disponíveis para as mais diversas atividades.

pacotes

Boa parte desses pacotes estão disponíveis no CRAN (Comprehensive R Archive Network), e podem ser instalados diretamente usando o comando install.packages().

Naturalmente, alguns pacotes são criados usando funções de outros pacotes. Isso cria um conjunto de dependências e faz com que a instalação de um pacote dispare um gatilho para a instalação de vários outros.

Por exemplo, para usar a função neuralnet() para criar redes neurais, instale o pacote neuralnet (neste caso, o mesmo nome) com install.packages("neuralnet") e carregue-o com library(neuralnet).

pacotes

Alguns desenvolvedores deixam pacotes disponíveis em links do Github. Para fazer a instalação desses pacotes, instale e carregue o pacote devtools:
install.packages("devtools"); library(devtools).
Devtools possui uma função chamada install_github(). Use install_github() passando o nome do desenvolvedor e o nome do pacote como uma única string no parâmetro (exemplo, “devA/libX”).

Exercícios

Teste seu entendimento e vá em direção da fluência.

Exercícios

1 - Crie um vetor de caracteres com a sequência 1 ate 99. Chame de vet1.
2 - Crie uma matrix 4x4 com valores de 1 até 16. Chame de mat1.
3 - Crie um data frame com a matriz anterior. Chame de DF1.
4 - Coloque nomes nas colunas do data frame (‘a’,‘b’,‘c’,‘d’).
5 - Crie uma lista com a,b,c. Depois substitua o ‘b’ por 2. Chame de lista1.
6 - Verifique que, em lista1, 2 é um valor numérico.
7 - Use a função summary para prever dados de sua matriz.
8 - Use um laço para criar um vetor chamado vet2 com a fórmula: vet1[i](i0.8), onde i é o índice do laço (1 … 99).
9 - Use plot e hist para visualizar o vetor vet2.
10 - Verifique a média, mediana e o terceiro quartil do vetor vet2.
11 - Carregue um arquivo .csv usando as funções url e read.csv.