6 Tipos de objetos

Os tipos básicos de objetos do Rsão:

Os quatro primeiros tipos são objetos que armazenam dados e que diferem entre si na forma da armazenar e operar com os dados. O último (função) é um tipo objeto especial que recebe algum "input"e produz um "output".

Experimente os comandos listados para se familiarizar com estas estruturas. Note que usamos as funções do tipo is.*() para testar se um objeto é de um determinado tipo. Estas funções são is.vector(), is.matrix(), is.array(), is.data.frame(), is.list(), is.function().

6.1 Vetores

Vetores são o tipo básico e mais simples de objeto para armazenar dados no R. O R é uma linguagem vetorial, e portanto capaz de operar vetores e matrizes diretamente sem a necessidade de "loops", como por exemplo em códigos C e/ou Fortran.

Nos exemplo a seguir mostramos algumas operações com vetores. A função c() ("c" de concaternar) é usada para criar um vetor. Os colchetes [ ] são usados para indicar seleção de elementos. As funções rep(), seq() e o símbolo ":" são usadas para facilitar a criação de vetores que tenham alguma lei de formação.

  > x1 <- 10
  > x1

  [1] 10

  > x2 <- c(1, 3, 6)
  > x2

  [1] 1 3 6

  > x2[1]

  [1] 1

  > x2[2]

  [1] 3

  > length(x2)

  [1] 3

  > is.vector(x2)

  [1] TRUE

  > is.matrix(x2)

  [1] FALSE

  > is.numeric(x2)

  [1] TRUE

  > is.character(x2)

  [1] FALSE

  > x3 <- 1:10
  > x3

   [1]  1  2  3  4  5  6  7  8  9 10

  > x4 <- seq(0, 1, by = 0.1)
  > x4

   [1] 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0

  > x4[x4 > 0.5]

  [1] 0.6 0.7 0.8 0.9 1.0

  > x4 > 0.5

   [1] FALSE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE

  > x5 <- seq(0, 1, len = 11)
  > x5

   [1] 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0

  > x6 <- rep(1, 5)
  > x6

  [1] 1 1 1 1 1

  > x7 <- rep(c(1, 2), c(3, 5))
  > x7

  [1] 1 1 1 2 2 2 2 2

  > x8 <- rep(1:3, rep(5, 3))
  > x8

   [1] 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3

Um escalar é um vetor de comprimento igual a 1. Os vetores podem ser compostos de números e caracteres ou apenas de um destes tipos. Portanto, adicionando um caracter a um vetor numérico este é transformado em um vetor alfanumérico.

  > x2

  [1] 1 3 6

  > c("a", x2)

  [1] "a" "1" "3" "6"

  > c(x2, "a")

  [1] "1" "3" "6" "a"

Diversas operações numéricas podem ser feitas sobre vetores. Uma característica importante da linguagem é a "lei da reciclagem" que permite operações sobre vetores de tamanhos diferentes.

  > x2

  [1] 1 3 6

  > x2 + 3

  [1] 4 6 9

  > x2 + 1:3

  [1] 2 5 9

  > x2 + 1:6

  [1]  2  5  9  5  8 12

  > (1:3) * x2

  [1]  1  6 18

  > x2/(1:6)

  [1] 1.00 1.50 2.00 0.25 0.60 1.00

  > x2^(1:3)

  [1]   1   9 216

Vetores são uma estrutura de dados sobre a qual podemos aplicar funções como por exemplo as que fornecem medidas estatísticas.

  > x9 <- round(rnorm(10, mean = 70, sd = 10))
  > x9

   [1] 73 91 57 77 65 75 59 96 91 70

  > sum(x9)

  [1] 754

  > mean(x9)

  [1] 75.4

  > var(x9)

  [1] 184.9333

  > min(x9)

  [1] 57

  > max(x9)

  [1] 96

  > summary(x9)

     Min. 1st Qu.  Median    Mean 3rd Qu.    Max.
    57.00   66.25   74.00   75.40   87.50   96.00

  > fivenum(x9)

  [1] 57 65 74 91 96

Criando vetores com elementos repetidos As funções rep() e seq() do R são úteis para criar vetores de dados que seguem um certo padrão.
Clique aqui para ver um arquivo de dados.
vamos ver os comandos que podem ser usados para criar vetores para cada uma das três colunas iniciais deste arquivo.

A primeira coluna pode ser obtida com um dos dois comandos mostrados inicialmente, a seguir. Os demais reproduzem a segunda e terceira coluna do arquivo de dados.

  > rep(1:4, each = 12)
  > rep(1:4, rep(12, 4))
  > rep(rep(1:3, each = 4), 4)
  > rep(1:4, 12)

Vetores lógicos e seleção de elementos Como dito anteriormente os colchetes [] são usados para selecionar elementos de um vetor. No exemplo abaixo vemos como selecionar os 3 primeiros elementos do vetor x9 criado anteriormente e depois os elementos em posição par no vetor (segundo, quarto, sexto, oitavo e décimo)

  > x9[1:3]

  [1] 73 91 57

  > x9[2 * (1:5)]

  [1] 91 77 75 96 70

Entretanto, a seleção de elementos é mais geral podendo atender a critérios definidos pelo usuário. A seguir mostramos que podemos criar um vetor lógico ind.72 que indica se cada valor de x9 é ou não maior que 72. O vetor pode ser ainda convertido para o formato de uma variável indicadora ("dummy").

  > ind.72 <- x9 > 72
  > ind.72

   [1]  TRUE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE  TRUE FALSE

  > as.numeric(ind.72)

   [1] 1 1 0 1 0 1 0 1 1 0

  > x10 <- x9[ind.72]
  > x10

  [1] 73 91 77 75 96 91

Vetores de caracteres Vetores de caracteres também são criados por c() com elementos entre aspas. Há também algumas funções para criação automática.

  > nomes <- c("fulano", "beltrano", "cicrano")
  > nomes

  [1] "fulano"   "beltrano" "cicrano"

  > let5 <- letters[1:5]
  > let5

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

  > let10 <- LETTERS[11:20]
  > let10

   [1] "K" "L" "M" "N" "O" "P" "Q" "R" "S" "T"

Uma função particularmente útil para criar vetores de caracteres é paste(). Examine os seguintes comandos.

  > paste(nomes, 1:3)

  [1] "fulano 1"   "beltrano 2" "cicrano 3"

  > paste("fulano", 2)

  [1] "fulano 2"

  > paste("fulano", 2, sep = "")

  [1] "fulano2"

  > paste(letters[1:8], 2, sep = "")

  [1] "a2" "b2" "c2" "d2" "e2" "f2" "g2" "h2"

Vejamos ainda mais um exemplo. Considere criar um vetor com elementos:

T1   T1   T1   T1   T2   T2   T2   T2   T3   T3   T3

  > rep(paste("T", 1:3, sep = ""), c(4, 4, 3))

   [1] "T1" "T1" "T1" "T1" "T2" "T2" "T2" "T2" "T3" "T3" "T3"

Fatores Comentamos anteriormente que os vetores podem ser numéricos ou de caracteres. Entretanto há mais um tipo importante de objeto: os fatores. Por exemplo, ao criar um vetor de indicadores de “tratamentos” em uma análise de experimentos devemos declarar este vetor como um “fator”. Portanto revisitando o exemplo visto anteriormente temos que uma forma mais adequada de usar o vetor como variável indicadora de tratamentos é defini-lo como um fator. Note que neste caso, diferentemente do anterior, são registrados os “níveis” (levels) do fator.

  > factor(rep(paste("T", 1:3, sep = ""), c(4, 4, 3)))

   [1] T1 T1 T1 T1 T2 T2 T2 T2 T3 T3 T3
  Levels: T1 T2 T3

É importante notar a diferença entre um vetor de caracteres e um vetor que seja um fator que são objetos de classes diferentes. O primeiro simplesmente guarda os seus elementos enquanto o segundo possui atributos que nesta caso incluem os níveis do fator. Nos comandos abaixo esta distinção fica mais clara onde um vetor é criado inicialmente como numérico e depois convertido para fator.

  > estados <- c("PR", "SC", "RS")
  > estados

  [1] "PR" "SC" "RS"

  > class(estados)

  [1] "character"

  > attributes(estados)

  NULL

  > estados <- factor(estados)
  > estados

  [1] PR SC RS
  Levels: PR RS SC

  > class(estados)

  [1] "factor"

  > attributes(estados)

  $levels
  [1] "PR" "RS" "SC"
  
  $class
  [1] "factor"

Um fato relevante a respeito da manipulação de fator é que uma seleção de parte dele que exclua um certo valor não exclui este valor dos atributos do vetor como no caso abaixo.

  > estados.sel <- estados[-3]
  > estados.sel

  [1] PR SC
  Levels: PR RS SC

Da mesma forma pode-se criar um vetor e definir para eles níveis, mesmos que estes níveis não estejam entre os elementos atualmente existentes no vetor. Note no exemplo abixo o que acontece com o valor "MG" em cada caso.

  > est <- c("SC", "PR", "SC", "PR", "RS", "SP", "RS", "SP", "ES", "PR",
  +     "RJ", "ES")
  > est

   [1] "SC" "PR" "SC" "PR" "RS" "SP" "RS" "SP" "ES" "PR" "RJ" "ES"

  > table(est)

  est
  ES PR RJ RS SC SP
   2  3  1  2  2  2

  > sesul <- factor(est, levels = c("PR", "SC", "RS", "MG", "SP", "RJ",
  +     "ES"))
  > sesul

   [1] SC PR SC PR RS SP RS SP ES PR RJ ES
  Levels: PR SC RS MG SP RJ ES

  > table(sesul)

  sesul
  PR SC RS MG SP RJ ES
   3  2  2  0  2  1  2

Fatores Ordenados Um tipo especial de fator é dado pelos fatores ordenados que são fatores para os quais preserva-se a ordenação natural dos níveis. No próximo exemplo vemos um vetor inicialmente definido como de caracteres e a diferença entre defini-lo como não-ordenado ou ordenado. A ordenação segue a ordem alfabética a menos que uma ordenação diferente seja definida pelo usuário no argumento levels. Note ainda é pode-se usar duas funções diferentes para definir fatores ordenados: factor(..., ord=T) ou ordered().

  > grau <- c("medio", "baixo", "medio", "alto", "baixo", "baixo", "alto",
  +     "medio", "alto", "medio")
  > factor(grau)

   [1] medio baixo medio alto  baixo baixo alto  medio alto  medio
  Levels: alto baixo medio

  > factor(grau, ord = T)

   [1] medio baixo medio alto  baixo baixo alto  medio alto  medio
  Levels: alto < baixo < medio

  > ordered(grau)

   [1] medio baixo medio alto  baixo baixo alto  medio alto  medio
  Levels: alto < baixo < medio

  > factor(grau, ord = T, levels = c("baixo", "medio", "alto"))

   [1] medio baixo medio alto  baixo baixo alto  medio alto  medio
  Levels: baixo < medio < alto

  > ordered(grau, levels = c("baixo", "medio", "alto"))

   [1] medio baixo medio alto  baixo baixo alto  medio alto  medio
  Levels: baixo < medio < alto

Mais algumas operações com vetores Considere o vetor vec obtido como se segue. As funções abaixo mostram como inverter a ordem dos elementos do vetor (rev()), ordenar os elementos ((sort()) e a posição de cada elemento no vetor ordenado e encontrar o "rank"dos elementos (rank()). As operações %% e %% fornecem, respectivamente, o resto e a parte inteira de uma divisão.

  > vec <- round(rnorm(7, m = 70, sd = 10))
  > vec

  [1] 83 66 83 73 81 63 71

  > rev(vec)

  [1] 71 63 81 73 83 66 83

  > sort(vec)

  [1] 63 66 71 73 81 83 83

  > order(vec)

  [1] 6 2 7 4 5 1 3

  > vec[order(vec)]

  [1] 63 66 71 73 81 83 83

  > rank(vec)

  [1] 6.5 2.0 6.5 4.0 5.0 1.0 3.0

  > vec%%5

  [1] 3 1 3 3 1 3 1

  > vec%/%5

  [1] 16 13 16 14 16 12 14

A função which retorna a posição do(s) elemento(s) que obedece a certo critério.

  > which(vec > 70)

  [1] 1 3 4 5 7

  > which.max(vec)

  [1] 1

  > which.min(vec)

  [1] 6

Outra operação é a remoção de elementos de vetores através de índices negativos.

  > vec

  [1] 83 66 83 73 81 63 71

  > vec[-5]

  [1] 83 66 83 73 63 71

  > vec[-(2:4)]

  [1] 83 81 63 71

Para mais detalhes sobre vetores você pode consultar ainda as seguinte páginas:

6.2 Matrizes

Matrizes são montadas a partir da reorganização de elementos de um vetor em linhas e colunas. Por “default” a matrix é preenchida por colunas e o argumento opcional byrow=T inverte este padrão. A seleção de elementos ou submatrizes é feita usando [,] sendo que antes da vírgula indica-se a(s) linha(s) e depois a(s) coluna(s) a serem selecionadas. Opcionalmente matrizes podem ter nomes associados às linhas e colunas ("rownames"e "colnames"). Cada um destes componentes da matrix é um vetor de nomes. Os comandos a seguir ilustram todas estas funcionalidades.

  > m1 <- matrix(1:12, ncol = 3)
  > m1

       [,1] [,2] [,3]
  [1,]    1    5    9
  [2,]    2    6   10
  [3,]    3    7   11
  [4,]    4    8   12

  > matrix(1:12, ncol = 3, byrow = T)

       [,1] [,2] [,3]
  [1,]    1    2    3
  [2,]    4    5    6
  [3,]    7    8    9
  [4,]   10   11   12

  > length(m1)

  [1] 12

  > dim(m1)

  [1] 4 3

  > nrow(m1)

  [1] 4

  > ncol(m1)

  [1] 3

  > m1[1, 2]

  [1] 5

  > m1[2, 2]

  [1] 6

  > m1[, 2]

  [1] 5 6 7 8

  > m1[3, ]

  [1]  3  7 11

  > m1[1:2, 2:3]

       [,1] [,2]
  [1,]    5    9
  [2,]    6   10

  > dimnames(m1)

  NULL

  > dimnames(m1) <- list(c("L1", "L2", "L3", "L4"), c("C1", "C2", "C3"))
  > dimnames(m1)

  [[1]]
  [1] "L1" "L2" "L3" "L4"
  
  [[2]]
  [1] "C1" "C2" "C3"

  > m1[c("L1", "L3"), ]

     C1 C2 C3
  L1  1  5  9
  L3  3  7 11

  > m1[c(1, 3), ]

     C1 C2 C3
  L1  1  5  9
  L3  3  7 11

  > m2 <- cbind(1:5, 6:10)
  > m2

       [,1] [,2]
  [1,]    1    6
  [2,]    2    7
  [3,]    3    8
  [4,]    4    9
  [5,]    5   10

  > m3 <- cbind(1:5, 6)
  > m3

       [,1] [,2]
  [1,]    1    6
  [2,]    2    6
  [3,]    3    6
  [4,]    4    6
  [5,]    5    6

Matrizes são muitas vezes utilizadas para armazenar frequências de cruzamentos entre variáveis. Desta forma é comum surgir a necessidade de obter os totais marginais, isto é a soma dos elementos das linhas e/ou colunas das matrizes, o que pode ser diretamente obtido com margin.table(). No caso de matrizes estas operação produz o mesmo resultado que outras funções conforme mostramos a seguir.

  > margin.table(m1, margin = 1)

  L1 L2 L3 L4
  15 18 21 24

  > apply(m1, 1, sum)

  L1 L2 L3 L4
  15 18 21 24

  > rowSums(m1)

  L1 L2 L3 L4
  15 18 21 24

  > margin.table(m1, margin = 2)

  C1 C2 C3
  10 26 42

  > apply(m1, 2, sum)

  C1 C2 C3
  10 26 42

  > colSums(m1)

  C1 C2 C3
  10 26 42

Operações com matrizes Operações com matrizes são feitas diretamente assim como no caso de vetores. A "lei da reciclagem"permanece válida. Existem diversas operações sobre matrizes e vamos apresentar apenas algumas aqui. Note que as operações abaixo são todas realizadas elemento a elemento.

  > m4 <- matrix(1:6, nc = 3)
  > m5 <- matrix(10 * (1:6), nc = 3)
  > m4

       [,1] [,2] [,3]
  [1,]    1    3    5
  [2,]    2    4    6

  > m5

       [,1] [,2] [,3]
  [1,]   10   30   50
  [2,]   20   40   60

  > m4 + m5

       [,1] [,2] [,3]
  [1,]   11   33   55
  [2,]   22   44   66

  > m4 * m5

       [,1] [,2] [,3]
  [1,]   10   90  250
  [2,]   40  160  360

  > m5 - m4

       [,1] [,2] [,3]
  [1,]    9   27   45
  [2,]   18   36   54

  > m5/m4

       [,1] [,2] [,3]
  [1,]   10   10   10
  [2,]   10   10   10

A multiplicação de matrizes é feita usando o operador %*%. A função t() faz transposição e a inversão é obtida com solve(). O pacote MASS fornece ginv() para obtenção de inversa generalizada (inversa de Moore-Penrose)

  > t(m4) %*% m5

       [,1] [,2] [,3]
  [1,]   50  110  170
  [2,]  110  250  390
  [3,]  170  390  610

A função solve() na verdade é mais geral e fornece a solução de um sistema de equações lineares. Por exemplo, a solução do sistema:

(
{  x + 3y - z   =  10
   5x - 2y + z  =  15
(  2x + y - z   =  7

pode ser obtida com:

  > mat <- matrix(c(1, 5, 2, 3, -2, 1, -1, 1, -1), nc = 3)
  > vec <- c(10, 15, 7)
  > solve(mat, vec)

  [1] 3.615385 3.307692 3.538462

Uma outra função muito útil para cálculos matriciais é crossprod() para produtos cruzados: crossprod(X) retorna XX crossprod(X,Y) retorna XY . Deve ser dada preferência a esta função sempre que possível pois é mais precisa e rápida do que o correspondente produto matricial com transposição do objeto do primeiro argumento.

Como exemplo vamos considerar as variáveis preditora e resposta com valores fornecidos na Tabela 6.2 e considere obter os coeficientes da regressão linear dados por:

ˆ         - 1
β = (X ′X )  X ′y  ,
(2)

onde X é a matrix com os valores da variável X acrescida de uma coluna de 1’s e y são os valores da variável resposta.


Tabela 2: Valores da variável preditora e resposta para uma regressão linear simples.











1 2 3 4 5 6 7 8 9 10










13.416.615.817.318.522.123.235.931.339.4











Nos comandos abaixo mostramos como entrar com os dados e como obter os resultados de duas formas: (i) usando operações de matrizes de forma "ineficiente"e usando uma forma computacionalmente mais adequada de obter o mesmo resultado.

  > X <- cbind(1, 1:10)
  > y <- c(13.4, 16.6, 15.8, 17.3, 18.5, 22.1, 23.2, 35.9, 31.3, 39.4)
  > solve(t(X) %*% X) %*% t(X) %*% y
       [,1]
  [1,] 8.06
  [2,] 2.78
  > solve(crossprod(X), crossprod(X, y))
       [,1]
  [1,] 8.06
  [2,] 2.78

Notas:

  1. existem formas ainda mais computacionalmente eficientes de obter o resultado acima no R, como por exemplo usando a decomposição QR, mas isto não será discutido neste ponto.
  2. na prática para ajustar regressões no R o usuário não precisa fazer operações como a indicada pois já existem funções no R (neste caso lm()) que efetuam o ajuste.

Para mais detalhes sobre matrizes consulte a página:

6.3 Arrays

O conceito de array generaliza a idéia de matrix. Enquanto em uma matrix os elementos são organizados em duas dimensões (linhas e colunas), em um array os elementos podem ser organizados em um número arbitrário de dimensões.

No R um array é definido utilizando a função array(). Defina um array com o comando a seguir e inspecione o objeto certificando-se que você entendeu como arrays são criados.

  > ar1 <- array(1:24, dim = c(3, 4, 2))
  > ar1

  , , 1
  
       [,1] [,2] [,3] [,4]
  [1,]    1    4    7   10
  [2,]    2    5    8   11
  [3,]    3    6    9   12
  
  , , 2
  
       [,1] [,2] [,3] [,4]
  [1,]   13   16   19   22
  [2,]   14   17   20   23
  [3,]   15   18   21   24

Examine agora os resultados dos seguintes comandos para selecionar e operar elementos do "array".

  > ar1[, 2:3, ]

  , , 1
  
       [,1] [,2]
  [1,]    4    7
  [2,]    5    8
  [3,]    6    9
  
  , , 2
  
       [,1] [,2]
  [1,]   16   19
  [2,]   17   20
  [3,]   18   21

  > ar1[2, , 1]

  [1]  2  5  8 11

  > sum(ar1[, , 1])

  [1] 78

  > sum(ar1[1:2, , 1])

  [1] 48

Podemos atribuir nomes às dimensões de um array.

  > dimnames(ar1)

  NULL

  > dimnames(ar1) <- list(c("Baixo", "Médio", "Alto"), paste("col",
  +     1:4, sep = ""), c("Masculino", "Feminino"))

Inspecione o “help” da função array (digite help(array)), rode e inspecione os exemplos contidos na documentação.

Veja agora um exemplo de dados já incluído no R no formato de array. Para “carregar” e visualizar os dados digite:

  > data(Titanic)
  > Titanic

  , , Age = Child, Survived = No
  
        Sex
  Class  Male Female
    1st     0      0
    2nd     0      0
    3rd    35     17
    Crew    0      0
  
  , , Age = Adult, Survived = No
  
        Sex
  Class  Male Female
    1st   118      4
    2nd   154     13
    3rd   387     89
    Crew  670      3
  
  , , Age = Child, Survived = Yes
  
        Sex
  Class  Male Female
    1st     5      1
    2nd    11     13
    3rd    13     14
    Crew    0      0
  
  , , Age = Adult, Survived = Yes
  
        Sex
  Class  Male Female
    1st    57    140
    2nd    14     80
    3rd    75     76
    Crew  192     20

Para obter maiores informações sobre estes dados digite:

  help(Titanic)

Agora vamos responder às seguintes perguntas, mostrando os comandos do R utilizados sobre o array de dados.

  1. quantas pessoas havia no total?
      > sum(Titanic)

      [1] 2201
  2. quantas pessoas havia na tripulação (crew)?
      > sum(Titanic[4, , , ])

      [1] 885
  3. quantas pessoas sobreviveram e quantas morreram?
      > apply(Titanic, 4, sum)

        No  Yes
      1490  711
  4. quantas crianças sobreviveram?
      > sum(Titanic[, , 1, 2])

      [1] 57
  5. quais as proporções de sobreviventes entre homens e mulheres?
    Vamos fazer por partes obtendo primeiro o número de homens e mulheres, depois dentre estes os que sobreviveram e depois obter as percentagens pedidas.
      > apply(Titanic, 2, sum)

        Male Female
        1731    470

      > apply(Titanic[, , , 2], 2, sum)

        Male Female
         367    344

      > 100 * apply(Titanic[, , , 2], 2, sum)/apply(Titanic, 2, sum)

          Male   Female
      21.20162 73.19149

Note-se ainda que assim como em matrizes, margin.table() poderia ser utilizada para obter os totais marginais para cada dimensão do array de dados, fornecendo uma maneira alternativa à alguns dos comandos mostrados acima.

  > margin.table(Titanic, margin = 1)

  Class
   1st  2nd  3rd Crew
   325  285  706  885

  > margin.table(Titanic, margin = 2)

  Sex
    Male Female
    1731    470

  > margin.table(Titanic, margin = 3)

  Age
  Child Adult
    109  2092

  > margin.table(Titanic, margin = 4)

  Survived
    No  Yes
  1490  711

Esta função admite ainda índices múltiplos que permitem outros resumos da tabela de dados. Por exemplo mostramos a seguir como obter o total de sobreviventes e não sobreviventes, separados por sexo e depois as porcentagens de sobreviventes para cada sexo.

  > margin.table(Titanic, margin = c(2, 4))

          Survived
  Sex        No  Yes
    Male   1364  367
    Female  126  344

  > prop.table(margin.table(Titanic, margin = c(2, 4)), margin = 1)

          Survived
  Sex             No       Yes
    Male   0.7879838 0.2120162
    Female 0.2680851 0.7319149

6.4 Data-frames

Vetores, matrizes e arrays forçam todos os elementos a serem do mesmo "tipo"i.e., ou numérico ou caracter. O "data-frame"é uma estrutura semelhante à uma matriz porém com cada coluna sendo tratada separadamente. Desta forma podemos ter colunas de valores numéricos e colunas de caracteres no mesmo objeto. Note entretanto que dentro de uma mesma coluna todos elementos ainda serão forçados a serem do mesmo tipo.

  > d1 <- data.frame(X = 1:10, Y = c(51, 54, 61, 67, 68, 75, 77, 75,
  +     80, 82))
  > d1

      X  Y
  1   1 51
  2   2 54
  3   3 61
  4   4 67
  5   5 68
  6   6 75
  7   7 77
  8   8 75
  9   9 80
  10 10 82

  > names(d1)

  [1] "X" "Y"

  > d1$X

   [1]  1  2  3  4  5  6  7  8  9 10

  > d1$Y

   [1] 51 54 61 67 68 75 77 75 80 82

  > plot(d1)
  > plot(d1$X, d1$Y)
  > d2 <- data.frame(Y = c(10 + rnorm(5, sd = 2), 16 + rnorm(5, sd = 2),
  +     14 + rnorm(5, sd = 2)))
  > d2$lev <- gl(3, 5)
  > d2

            Y lev
  1  14.35972   1
  2  10.57823   1
  3  11.19100   1
  4  10.44532   1
  5  12.50729   1
  6  14.57557   2
  7  16.36979   2
  8  18.51120   2
  9  14.20450   2
  10 20.36193   2
  11 14.59282   3
  12 13.32687   3
  13 14.12779   3
  14 13.13010   3
  15 13.35594   3

  > by(d2$Y, d2$lev, summary)

  INDICES: 1
     Min. 1st Qu.  Median    Mean 3rd Qu.    Max.
    10.45   10.58   11.19   11.82   12.51   14.36
  ---------------------------------------------------------------
  INDICES: 2
     Min. 1st Qu.  Median    Mean 3rd Qu.    Max.
    14.20   14.58   16.37   16.80   18.51   20.36
  ---------------------------------------------------------------
  INDICES: 3
     Min. 1st Qu.  Median    Mean 3rd Qu.    Max.
    13.13   13.33   13.36   13.71   14.13   14.59

  > d3 <- expand.grid(1:3, 4:5)
  > d3

    Var1 Var2
  1    1    4
  2    2    4
  3    3    4
  4    1    5
  5    2    5
  6    3    5

Na criação de data-frame expand.grid() pode ser muito útil gerando autimaticamente combinações de valores.

  > expand.grid(1:3, 1:2)

    Var1 Var2
  1    1    1
  2    2    1
  3    3    1
  4    1    2
  5    2    2
  6    3    2

Para mais detalhes sobre data-frame consulte a página:

6.5 Listas

Listas são estruturas genéricas e flexíveis que permitem armazenar diversos formatos em um único objeto.

  > lis1 <- list(A = 1:10, B = "THIS IS A MESSAGE", C = matrix(1:9,
  +     ncol = 3))
  > lis1

  $A
   [1]  1  2  3  4  5  6  7  8  9 10
  
  $B
  [1] "THIS IS A MESSAGE"
  
  $C
       [,1] [,2] [,3]
  [1,]    1    4    7
  [2,]    2    5    8
  [3,]    3    6    9

  > lis2 <- lm(Y ~ X, data = d1)
  > lis2

  Call:
  lm(formula = Y ~ X, data = d1)
  
  Coefficients:
  (Intercept)            X
       50.067        3.442

  > is.list(lis2)

  [1] TRUE

  > class(lis2)

  [1] "lm"

  > summary(lis2)

  Call:
  lm(formula = Y ~ X, data = d1)
  
  Residuals:
      Min      1Q  Median      3Q     Max
  -2.9515 -2.5045 -0.2212  2.3076  4.2788
  
  Coefficients:
              Estimate Std. Error t value Pr(>|t|)
  (Intercept)  50.0667     1.9674   25.45 6.09e-09 ***
  X             3.4424     0.3171   10.86 4.58e-06 ***
  ---
  Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
  
  Residual standard error: 2.88 on 8 degrees of freedom
  Multiple R-squared: 0.9364, Adjusted R-squared: 0.9285
  F-statistic: 117.9 on 1 and 8 DF,  p-value: 4.579e-06

  > anova(lis2)

  Analysis of Variance Table
  
  Response: Y
            Df Sum Sq Mean Sq F value    Pr(>F)
  X          1 977.65  977.65  117.88 4.579e-06 ***
  Residuals  8  66.35    8.29
  ---
  Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

  > names(lis2)

   [1] "coefficients"  "residuals"     "effects"       "rank"          "fitted.values"
   [6] "assign"        "qr"            "df.residual"   "xlevels"       "call"
  [11] "terms"         "model"

  > lis2$pred

  NULL

  > lis2$res

           1          2          3          4          5          6          7
  -2.5090909 -2.9515152  0.6060606  3.1636364  0.7212121  4.2787879  2.8363636
           8          9         10
  -2.6060606 -1.0484848 -2.4909091

  > plot(lis2)
  > lis3 <- aov(Y ~ lev, data = d2)
  > lis3

  Call:
     aov(formula = Y ~ lev, data = d2)
  
  Terms:
                       lev Residuals
  Sum of Squares  63.42251  39.79740
  Deg. of Freedom        2        12
  
  Residual standard error: 1.821112
  Estimated effects may be unbalanced

  > summary(lis3)

              Df Sum Sq Mean Sq F value   Pr(>F)
  lev          2 63.423  31.711  9.5618 0.003285 **
  Residuals   12 39.797   3.316
  ---
  Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Uma lista é portanto uma coleção de objetos. Para listas há duas opções para se selecionar elementos: colchetes [ ] ou colchetes duplos [[ ]]. Entretanto os resultados retornados por cada um destes é diferente. Ou seja, o colchete simples ([ ]) retorna uma parte da lista, ou seja, retorna um objeto que ainda é uma lista. Já o colchete duplo ([[ ]]) retorna o objeto que está na posição indicada da lista. Examine o exemplo a seguir.

  > lis1 <- list(nomes = c("Pedro", "Joao", "Maria"), mat = matrix(1:6,
  +     nc = 2))
  > lis1

  $nomes
  [1] "Pedro" "Joao"  "Maria"
  
  $mat
       [,1] [,2]
  [1,]    1    4
  [2,]    2    5
  [3,]    3    6

  > lis1[1]

  $nomes
  [1] "Pedro" "Joao"  "Maria"

  > lis1[2]

  $mat
       [,1] [,2]
  [1,]    1    4
  [2,]    2    5
  [3,]    3    6

  > lis1[[2]]

       [,1] [,2]
  [1,]    1    4
  [2,]    2    5
  [3,]    3    6

6.6 Funções

O conteúdo das funções podem ser vistos digitando o nome da função (sem os parênteses).

  lm
  glm
  plot
  plot.default

Entretanto isto não é disponível desta forma para todas as funções como por exemplo em min, max, rnorm e lines Nestes casos as funções não são escritas em linguagem R (em geral estão escritas em C) e para visualizar o conteúdo das funções você tem que examinar os arquivos do código fonte do R.

6.7 Que tipo de objeto eu tenho?

As funções do tipo is.*() mencionadas no início dasta sessão podem ser usadas para obter informações sobre a natureza de um objeto, o que pode sem muito útil quando se escreve funções em R. Entretanto são pouco práticas para determinar qual o tipo de um objeto e retornam apenas um valor lógico TRUE ou FALSE.

Uma função mais rica em detalhes é str() retorna informações sobre a estrutura do objeto. Nos exemplos a seguir vemos que a função informa sobre objecots que criamos anteriormente: x1 é um vetor numérico, estado é um fator om três níveis, ar1 é um array, d1 é um data.frame com duas variáveis sendo uma delas de valores inteiros e a outra de valores numéricos e lis1 é uma lista de dois elementos sendo o primeiro um vetor de caracteres e o segundo uma matrix de seis elementos e de dimensão 3 × 2.

  > str(x1)

   num 10

  > str(estados)

   Factor w/ 3 levels "PR","RS","SC": 1 3 2

  > str(ar1)

   int [1:3, 1:4, 1:2] 1 2 3 4 5 6 7 8 9 10 ...
   - attr(*, "dimnames")=List of 3
    ..$ : chr [1:3] "Baixo" "Médio" "Alto"
    ..$ : chr [1:4] "col1" "col2" "col3" "col4"
    ..$ : chr [1:2] "Masculino" "Feminino"

  > str(d1)

  'data.frame': 10 obs. of  2 variables:
   $ X: int  1 2 3 4 5 6 7 8 9 10
   $ Y: num  51 54 61 67 68 75 77 75 80 82

  > str(lis1)

  List of 2
   $ nomes: chr [1:3] "Pedro" "Joao" "Maria"
   $ mat  : int [1:3, 1:2] 1 2 3 4 5 6

6.8 Exercícios

  1. Mostrar comandos que podem ser usados para criar os objetos ou executar as instruções a seguir

    1. o vetor
        [1] 4 8 2
    2. selecionar o primeiro e terceiro elemento do vetor acima
    3. 10
    4. o vetor com a seqüência de valores
        [1] -3 -2 -1  0  1  2  3
    5. o vetor com a seqüência de valores
        [1]  2.4  3.4  4.4  5.4  6.4  7.4  8.4  9.4 10.4
    6. o vetor
         [1]  1  3  5  7  9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39
    7. o vetor
        [1]  1  3  5  7  9 11 14 17 20
    8. o vetor de seqüência repetida
         [1] 1 1 1 2 2 2 3 3 3 4 4 4
    9. o vetor de seqüência repetida
         [1] 4 4 4 3 3 3 2 2 2 1 1 1
    10. o vetor de elementos repetidos
         [1] 1 2 3 1 2 3 1 2 3 1 2 3
    11. a seqüência de valores
         [1]  1  3  5  7  9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49 51 53
        [28] 55 57 59 61 63 65 67 69 71 73 75 77 79 81 83 85 87 89 91 93 95 97 99
    12. o vetor
         [1] 11 10  9  8  7  6  5  4  3  2  1
    13. o vetor alfanumérico
        [1] "Parana"       "Sao Paulo"    "Minas Gerais"
    14. o vetor indicador de tratamentos
         [1] Trat_1 Trat_1 Trat_1 Trat_2 Trat_2 Trat_2 Trat_3 Trat_3 Trat_3 Trat_4 Trat_4
        [12] Trat_4
        Levels: Trat_1 Trat_2 Trat_3 Trat_4
    15. um vetor indicador de blocos
         [1] Bloco_1 Bloco_2 Bloco_3 Bloco_1 Bloco_2 Bloco_3 Bloco_1 Bloco_2 Bloco_3 Bloco_1
        [11] Bloco_2 Bloco_3
        Levels: Bloco_1 Bloco_2 Bloco_3
  2. Mostre comando(s) para construir uma matriz 10 × 10 tal que as entradas são iguais a i*j, sendo i a linha e j a coluna.
  3. Construa um data-frame com uma tabela com três colunas: x, x2 e exp(x), com x variando de 0 a 50.
  4. A função sum(x) retorna a soma dos elementos do vetor x. A expressão z<-rep(x,10) faz o vetor z igual a uma seqüência de 10 vetores x. Use estas e outras funções para calcular a soma dos 100 primeiros termos das séries:
  5. Carregue o conjunto de dados com o comando
    data(HairEyeColor)

    e responda as seguintes perguntas fornecendo também o comando do R para obter a resposta:

    1. Qual a proporção de homens e mulheres na amostra?
    2. Quantos são os homens de cabelos pretos?
    3. Quantas mulheres tem cabelos loiros?
    4. Qual a proporção de homens e mulheres entre as pessoas ruivas?
    5. Quantas pessoas tem olhos verdes?
  6. Considere a tabela de freqüências a seguir. Entre com os dados usando o tipo de objeto adequado e mostre os comandos para responder as perguntas abaixo.

    Fumante
    Não Fumante




    Idade MasculinoFemininoMasculinoFeminino






    Menor que 20 50 30 55 41
    20 a 40 39 28 31 30
    Maior que 40 37 36 25 15






    1. qual o número total de pessoas?
    2. quantos são os fumantes e os não fumantes?
    3. quantos são homens?
    4. quantas mulheres são não fumantes?
    5. quais as proporções de fumantes entre homens e mulheres?