Universidade Federal do Paraná
Curso de Estatística
CE 083 -
Estatística Computacional I - 2014/2
Prof. Dr. Walmes Marques Zeviani
Tabela de conteúdo
##-----------------------------------------------------------------------------
## Funções que fazem conversão. Conversões podem ser de conteúdo (ex:
## numeric -> character, factor -> integer) e podem ser formatos (ex:
## matrix -> vector, vector -> list). Outros tipos podem existir, como
## conversões de classe.
## Funções de conversão. Começam com `as.`.
a <- apropos("^as\\."); a
## [1] "as.array" "as.array.default"
## [3] "as.call" "as.character"
## [5] "as.character.condition" "as.character.Date"
## [7] "as.character.default" "as.character.error"
## [9] "as.character.factor" "as.character.hexmode"
## [11] "as.character.numeric_version" "as.character.octmode"
## [13] "as.character.POSIXt" "as.character.srcref"
## [15] "as.complex" "as.data.frame"
## [17] "as.data.frame.array" "as.data.frame.AsIs"
## [19] "as.data.frame.character" "as.data.frame.complex"
## [21] "as.data.frame.data.frame" "as.data.frame.Date"
## [23] "as.data.frame.default" "as.data.frame.difftime"
## [25] "as.data.frame.factor" "as.data.frame.integer"
## [27] "as.data.frame.list" "as.data.frame.logical"
## [29] "as.data.frame.matrix" "as.data.frame.model.matrix"
## [31] "as.data.frame.numeric" "as.data.frame.numeric_version"
## [33] "as.data.frame.ordered" "as.data.frame.POSIXct"
## [35] "as.data.frame.POSIXlt" "as.data.frame.raw"
## [37] "as.data.frame.table" "as.data.frame.ts"
## [39] "as.data.frame.vector" "as.Date"
## [41] "as.Date.character" "as.Date.date"
## [43] "as.Date.dates" "as.Date.default"
## [45] "as.Date.factor" "as.Date.numeric"
## [47] "as.Date.POSIXct" "as.Date.POSIXlt"
## [49] "as.dendrogram" "as.difftime"
## [51] "as.dist" "as.double"
## [53] "as.double.difftime" "as.double.POSIXlt"
## [55] "as.environment" "as.expression"
## [57] "as.expression.default" "as.factor"
## [59] "as.formula" "as.function"
## [61] "as.function.default" "as.graphicsAnnot"
## [63] "as.hclust" "as.hexmode"
## [65] "as.integer" "as.list"
## [67] "as.list.data.frame" "as.list.Date"
## [69] "as.list.default" "as.list.environment"
## [71] "as.list.factor" "as.list.function"
## [73] "as.list.numeric_version" "as.list.POSIXct"
## [75] "as.logical" "as.logical.factor"
## [77] "as.matrix" "as.matrix.data.frame"
## [79] "as.matrix.default" "as.matrix.noquote"
## [81] "as.matrix.POSIXlt" "as.name"
## [83] "as.null" "as.null.default"
## [85] "as.numeric" "as.numeric_version"
## [87] "as.octmode" "as.ordered"
## [89] "as.package_version" "as.pairlist"
## [91] "as.person" "as.personList"
## [93] "as.POSIXct" "as.POSIXct.date"
## [95] "as.POSIXct.Date" "as.POSIXct.dates"
## [97] "as.POSIXct.default" "as.POSIXct.numeric"
## [99] "as.POSIXct.POSIXlt" "as.POSIXlt"
## [101] "as.POSIXlt.character" "as.POSIXlt.date"
## [103] "as.POSIXlt.Date" "as.POSIXlt.dates"
## [105] "as.POSIXlt.default" "as.POSIXlt.factor"
## [107] "as.POSIXlt.numeric" "as.POSIXlt.POSIXct"
## [109] "as.qr" "as.raster"
## [111] "as.raw" "as.relistable"
## [113] "as.roman" "as.single"
## [115] "as.single.default" "as.stepfun"
## [117] "as.symbol" "as.table"
## [119] "as.table.default" "as.ts"
## [121] "as.vector" "as.vector.factor"
## Aquelas que contém no nome dos tipos de objetos já vistos.
grep("(list|vector|matrix|array|frame)", a, value=TRUE)
## [1] "as.array" "as.array.default"
## [3] "as.data.frame" "as.data.frame.array"
## [5] "as.data.frame.AsIs" "as.data.frame.character"
## [7] "as.data.frame.complex" "as.data.frame.data.frame"
## [9] "as.data.frame.Date" "as.data.frame.default"
## [11] "as.data.frame.difftime" "as.data.frame.factor"
## [13] "as.data.frame.integer" "as.data.frame.list"
## [15] "as.data.frame.logical" "as.data.frame.matrix"
## [17] "as.data.frame.model.matrix" "as.data.frame.numeric"
## [19] "as.data.frame.numeric_version" "as.data.frame.ordered"
## [21] "as.data.frame.POSIXct" "as.data.frame.POSIXlt"
## [23] "as.data.frame.raw" "as.data.frame.table"
## [25] "as.data.frame.ts" "as.data.frame.vector"
## [27] "as.list" "as.list.data.frame"
## [29] "as.list.Date" "as.list.default"
## [31] "as.list.environment" "as.list.factor"
## [33] "as.list.function" "as.list.numeric_version"
## [35] "as.list.POSIXct" "as.matrix"
## [37] "as.matrix.data.frame" "as.matrix.default"
## [39] "as.matrix.noquote" "as.matrix.POSIXlt"
## [41] "as.pairlist" "as.relistable"
## [43] "as.vector" "as.vector.factor"
##-----------------------------------------------------------------------------
## Conversões de forma sobre um vetor.
x <- runif(12)
## Veja que é um vetor.
c(is.vector(x), is.matrix(x), is.array(x), is.list(x), is.data.frame(x))
## [1] TRUE FALSE FALSE FALSE FALSE
## Vetor é a forma mais básica de organizar dados. Tem uma só dimensão e
## todos os elementos são do mesmo tipo de conteúdo. Assim, pode-se sem
## restrições convertê-lo para objetos de estrutura mais complexa.
##-----------------------------------------------------------------------------
## Para matriz.
y <- as.matrix(x)
c(is.vector(y), is.matrix(y), is.array(y), is.list(y), is.data.frame(y))
## [1] FALSE TRUE TRUE FALSE FALSE
class(y)
## [1] "matrix"
str(y)
## num [1:12, 1] 0.739 0.838 0.626 0.714 0.189 ...
## Pode transformar em matriz forçando a existência de um atributo
## típico de matrizes, como nrow, ncol e dim.
y <- x
c(is.vector(y), is.matrix(y), is.array(y), is.list(y), is.data.frame(y))
## [1] TRUE FALSE FALSE FALSE FALSE
dim(y)
## NULL
dim(y) <- c(3,4)
c(is.vector(y), is.matrix(y), is.array(y), is.list(y), is.data.frame(y))
## [1] FALSE TRUE TRUE FALSE FALSE
y
## [,1] [,2] [,3] [,4]
## [1,] 0.7391 0.7137 0.9478 0.1132
## [2,] 0.8381 0.1886 0.3553 0.3114
## [3,] 0.6262 0.2546 0.2190 0.7837
##-----------------------------------------------------------------------------
## Para arranjo (matriz é arranjo de duas dimensões).
y <- as.array(x)
c(is.vector(y), is.matrix(y), is.array(y), is.list(y), is.data.frame(y))
## [1] FALSE FALSE TRUE FALSE FALSE
class(y)
## [1] "array"
str(y)
## num [1:12(1d)] 0.739 0.838 0.626 0.714 0.189 ...
## Pode-se convertê-lo para array atribuindo dimensões.
y <- x
c(is.vector(y), is.matrix(y), is.array(y), is.list(y), is.data.frame(y))
## [1] TRUE FALSE FALSE FALSE FALSE
dim(y)
## NULL
dim(y) <- c(3,2,2)
c(is.vector(y), is.matrix(y), is.array(y), is.list(y), is.data.frame(y))
## [1] FALSE FALSE TRUE FALSE FALSE
y
## , , 1
##
## [,1] [,2]
## [1,] 0.7391 0.7137
## [2,] 0.8381 0.1886
## [3,] 0.6262 0.2546
##
## , , 2
##
## [,1] [,2]
## [1,] 0.9478 0.1132
## [2,] 0.3553 0.3114
## [3,] 0.2190 0.7837
##-----------------------------------------------------------------------------
## Para data.frame (tabela).
y <- as.data.frame(x)
str(y)
## 'data.frame': 12 obs. of 1 variable:
## $ x: num 0.739 0.838 0.626 0.714 0.189 ...
y
## x
## 1 0.7391
## 2 0.8381
## 3 0.6262
## 4 0.7137
## 5 0.1886
## 6 0.2546
## 7 0.9478
## 8 0.3553
## 9 0.2190
## 10 0.1132
## 11 0.3114
## 12 0.7837
##-----------------------------------------------------------------------------
## Para lista.
y <- as.list(x)
str(y)
## List of 12
## $ : num 0.739
## $ : num 0.838
## $ : num 0.626
## $ : num 0.714
## $ : num 0.189
## $ : num 0.255
## $ : num 0.948
## $ : num 0.355
## $ : num 0.219
## $ : num 0.113
## $ : num 0.311
## $ : num 0.784
##-----------------------------------------------------------------------------
## Conversões a partir de matrizes e arranjos.
m <- matrix(runif(12), 3, 4)
m
## [,1] [,2] [,3] [,4]
## [1,] 0.02899 0.4460 0.6971 0.5420
## [2,] 0.73112 0.4200 0.1558 0.5841
## [3,] 0.23062 0.4027 0.6761 0.5728
c(is.vector(m), is.matrix(m), is.array(m), is.list(m), is.data.frame(m))
## [1] FALSE TRUE TRUE FALSE FALSE
##-----------------------------------------------------------------------------
## Para vetor.
n <- as.vector(m)
str(n)
## num [1:12] 0.029 0.731 0.231 0.446 0.42 ...
## A matriz tem as colunas emplilhadas para gerar o vetor. Sempre será
## assim, as dimensões de maior ordem são desfeitas depois das de menor
## ordem. Para ficar claro, veja como fica com um arranjo de 4
## dimensões.
a <- array(sample(0:9, 3*3*2*2, repl=TRUE), dim=c(3,3,2,2))
str(a)
## int [1:3, 1:3, 1:2, 1:2] 4 2 3 9 9 6 6 8 6 2 ...
a
## , , 1, 1
##
## [,1] [,2] [,3]
## [1,] 4 9 6
## [2,] 2 9 8
## [3,] 3 6 6
##
## , , 2, 1
##
## [,1] [,2] [,3]
## [1,] 2 4 7
## [2,] 8 8 9
## [3,] 5 4 5
##
## , , 1, 2
##
## [,1] [,2] [,3]
## [1,] 3 2 6
## [2,] 2 2 6
## [3,] 8 5 6
##
## , , 2, 2
##
## [,1] [,2] [,3]
## [1,] 7 1 4
## [2,] 5 3 0
## [3,] 9 4 1
as.vector(a)
## [1] 4 2 3 9 9 6 6 8 6 2 8 5 4 8 4 7 9 5 3 2 8 2 2 5 6 6 6 7 5 9 1 3 4 4 0 1
##-----------------------------------------------------------------------------
## Para data.frame.
n <- as.data.frame(m)
str(n)
## 'data.frame': 3 obs. of 4 variables:
## $ V1: num 0.029 0.731 0.231
## $ V2: num 0.446 0.42 0.403
## $ V3: num 0.697 0.156 0.676
## $ V4: num 0.542 0.584 0.573
n <- as.data.frame(t(m))
str(n)
## 'data.frame': 4 obs. of 3 variables:
## $ V1: num 0.029 0.446 0.697 0.542
## $ V2: num 0.731 0.42 0.156 0.584
## $ V3: num 0.231 0.403 0.676 0.573
##-----------------------------------------------------------------------------
## Para lista.
n <- as.list(m)
str(n)
## List of 12
## $ : num 0.029
## $ : num 0.731
## $ : num 0.231
## $ : num 0.446
## $ : num 0.42
## $ : num 0.403
## $ : num 0.697
## $ : num 0.156
## $ : num 0.676
## $ : num 0.542
## $ : num 0.584
## $ : num 0.573
## Aqui vê-se que a matriz passou para vetor e depois para lista. Caso
## se quisesse que cada coluna (ou linha) fosse um item da lista
## teria-se que proceder de outra forma. Uma forma e passando antes para
## data.frame a outra é usando uma função da família *apply.
##-----------------------------------------------------------------------------
## Conversões a partir de data.frames.
## d <- mtcars
d <- trees
c(is.vector(d), is.matrix(d), is.array(d), is.list(d), is.data.frame(d))
## [1] FALSE FALSE FALSE TRUE TRUE
str(d)
## 'data.frame': 31 obs. of 3 variables:
## $ Girth : num 8.3 8.6 8.8 10.5 10.7 10.8 11 11 11.1 11.2 ...
## $ Height: num 70 65 63 72 81 83 66 75 80 75 ...
## $ Volume: num 10.3 10.3 10.2 16.4 18.8 19.7 15.6 18.2 22.6 19.9 ...
e <- as.vector(d)
str(e)
## 'data.frame': 31 obs. of 3 variables:
## $ Girth : num 8.3 8.6 8.8 10.5 10.7 10.8 11 11 11.1 11.2 ...
## $ Height: num 70 65 63 72 81 83 66 75 80 75 ...
## $ Volume: num 10.3 10.3 10.2 16.4 18.8 19.7 15.6 18.2 22.6 19.9 ...
## Não deu efeito efeito. Caso realmente queira que um data.frame seja
## decomposto e vire vetor tem que antes passar por matriz. Mas deve ser
## lembrado que um data.frame permite que cada coluna tenha conteúdo de
## tipo próprio e numa matriz o conteúdo deve ser do mesmo tipo.
is.list(d)
## [1] TRUE
## Note que data.frame é um tipo especial de lista no qual as colunas
## são os itens e esses itens são todos vetores de mesmo comprimento, o
## que permite que eles sejam acomodados lado a lado (como coluna) em um
## data.frame.
as.list(d)
## $Girth
## [1] 8.3 8.6 8.8 10.5 10.7 10.8 11.0 11.0 11.1 11.2 11.3 11.4 11.4 11.7 12.0 12.9 12.9
## [18] 13.3 13.7 13.8 14.0 14.2 14.5 16.0 16.3 17.3 17.5 17.9 18.0 18.0 20.6
##
## $Height
## [1] 70 65 63 72 81 83 66 75 80 75 79 76 76 69 75 74 85 86 71 64 78 80 74 72 77 81 82 80
## [29] 80 80 87
##
## $Volume
## [1] 10.3 10.3 10.2 16.4 18.8 19.7 15.6 18.2 22.6 19.9 24.2 21.0 21.4 21.3 19.1 22.2 33.8
## [18] 27.4 25.7 24.9 34.5 31.7 36.3 38.3 42.6 55.4 55.7 58.3 51.5 51.0 77.0
##-----------------------------------------------------------------------------
## Conversões a partir de listas.
## Uma lista com conteúdo regular: os itens são vetores de mesmo tamanho
## e mesmo tipo de conteúdo.
l <- list(a=1:5, b=runif(5), c=sample(0:1, 5, repl=TRUE))
l
## $a
## [1] 1 2 3 4 5
##
## $b
## [1] 0.71683 0.57932 0.12778 0.99206 0.06632
##
## $c
## [1] 0 0 1 1 1
## as.vector(l) ## Não.
## as.array(l) ## Não.
as.data.frame(l) ## Sim.
## a b c
## 1 1 0.71683 0
## 2 2 0.57932 0
## 3 3 0.12778 1
## 4 4 0.99206 1
## 5 5 0.06632 1
## Conteúdo irregular: diferentes comprimentos ou tipos de formato.
l <- list(a=1:5, b=runif(5), c=sample(0:1, 5, repl=TRUE),
d=matrix(1:9, 3, 3), e=head(iris))
l
## $a
## [1] 1 2 3 4 5
##
## $b
## [1] 0.02573 0.03268 0.02440 0.79516 0.56491
##
## $c
## [1] 0 1 1 1 1
##
## $d
## [,1] [,2] [,3]
## [1,] 1 4 7
## [2,] 2 5 8
## [3,] 3 6 9
##
## $e
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 5.1 3.5 1.4 0.2 setosa
## 2 4.9 3.0 1.4 0.2 setosa
## 3 4.7 3.2 1.3 0.2 setosa
## 4 4.6 3.1 1.5 0.2 setosa
## 5 5.0 3.6 1.4 0.2 setosa
## 6 5.4 3.9 1.7 0.4 setosa
as.data.frame(l)
## Error: arguments imply differing number of rows: 5, 3, 6
## Passar de um objeto mais simples para um mais complexo é possível,
## pois é *simples complicar* mas de um complexo para um simples requer
## que muitos requisitos sejam satisfeitos e por isso é *complicado
## simplificar*.
##-----------------------------------------------------------------------------
## Os objetos retornados por funções do R são em geral em forma de lista
## porque facilmente eles podem diferir em dimensão, tipo de conteúdo e
## forma, o que impede uso de estruturas simples. Abaixo de uma lista
## obtida ao fazer um histograma será gerada uma tabela com frequências
## e pontos centrais e extremos dos limites de cada classe.
## Um vetor com os valores de precipitação pluviométrica (chuva
## acumulada) para cidades dos USA.
str(precip)
## Named num [1:70] 67 54.7 7 48.5 14 17.2 20.7 13 43.4 40.2 ...
## - attr(*, "names")= chr [1:70] "Mobile" "Juneau" "Phoenix" "Little Rock" ...
h <- hist(precip, col="seagreen")
str(h)
## List of 6
## $ breaks : num [1:8] 0 10 20 30 40 50 60 70
## $ counts : int [1:7] 4 9 5 25 21 5 1
## $ density : num [1:7] 0.00571 0.01286 0.00714 0.03571 0.03 ...
## $ mids : num [1:7] 5 15 25 35 45 55 65
## $ xname : chr "precip"
## $ equidist: logi TRUE
## - attr(*, "class")= chr "histogram"
## Quer-se uma tabelas com os extremos e meio das classes além das
## frequências absolutas e relativas, simples e acumuladas.
## Pega os itens counts e mids.
l <- h[c(2,4)]
str(l)
## List of 2
## $ counts: int [1:7] 4 9 5 25 21 5 1
## $ mids : num [1:7] 5 15 25 35 45 55 65
n <- length(h$mids); n ## Número de classes
## [1] 7
## Adiciona os limites inferiores e superiores das classes.
l$lwr <- h$breaks[1:n]
l$upr <- h$breaks[1:n+1]
## A frequência acumulada.
l$fac <- cumsum(l$counts)
## As relativas.
l$freq <- l$counts/sum(l$counts)
l$facr <- l$fac/sum(l$counts)
## A tabela desejada.
as.data.frame(l)
## counts mids lwr upr fac freq facr
## 1 4 5 0 10 4 0.05714 0.05714
## 2 9 15 10 20 13 0.12857 0.18571
## 3 5 25 20 30 18 0.07143 0.25714
## 4 25 35 30 40 43 0.35714 0.61429
## 5 21 45 40 50 64 0.30000 0.91429
## 6 5 55 50 60 69 0.07143 0.98571
## 7 1 65 60 70 70 0.01429 1.00000
*apply
##-----------------------------------------------------------------------------
## Os membros da família *apply.
cat(cbind(apropos("apply$")), sep="\n")
## apply
## dendrapply
## eapply
## kernapply
## lapply
## mapply
## .mapply
## rapply
## sapply
## tapply
## vapply
## De uso simples e frequente.
## apply : on Arrays margins (não é aaply para evitar cacofonia).
## lapply : on Lists itens or vector elements or data.frame columns.
## sapply : lapply that Simplifies when possible.
## tapply : on a ragged array, return as Tabular format.
## De uso menos frequente.
## mapply : lapply over Multiple list or vector arguments.
## eapply : on Environments.
## rapply : Recursive.
## vapply : Vectorized.
## dendrapply : related to dendrogramns.
## kernapply : related kernel.
## Além destas, as funções by() e aggragate() são úteis e são agregados
## da notável família.
##-----------------------------------------------------------------------------
## tapply.
str(npk)
## 'data.frame': 24 obs. of 5 variables:
## $ block: Factor w/ 6 levels "1","2","3","4",..: 1 1 1 1 2 2 2 2 3 3 ...
## $ N : Factor w/ 2 levels "0","1": 1 2 1 2 2 2 1 1 1 2 ...
## $ P : Factor w/ 2 levels "0","1": 2 2 1 1 1 2 1 2 2 2 ...
## $ K : Factor w/ 2 levels "0","1": 2 1 1 2 1 2 2 1 1 2 ...
## $ yield: num 49.5 62.8 46.8 57 59.8 58.5 55.5 56 62.8 55.8 ...
## Média de yield para cada nível de N.
r <- tapply(npk$yield, npk$N, mean)
r
## 0 1
## 52.07 57.68
class(r)
## [1] "array"
## Média de yield para combinando os níveis de N e P.
r <- tapply(npk$yield, list(npk$N, npk$P), mean)
r
## 0 1
## 0 51.72 52.42
## 1 59.22 56.15
## Melhor usa com with() para simplificar a declaração.
r <- with(npk, tapply(yield, list(N, P), mean))
r
## 0 1
## 0 51.72 52.42
## 1 59.22 56.15
## O mesmo considerando N, P e K.
r <- with(npk, tapply(yield, list(N, P, K), mean))
r
## , , 0
##
## 0 1
## 0 51.43 54.33
## 1 63.77 57.93
##
## , , 1
##
## 0 1
## 0 52.00 50.50
## 1 54.67 54.37
## Nomes na lista geram nomes para as dimensões do array.
r <- with(npk, tapply(yield, list(Nitro=N, Phos=P, Pot=K), mean))
r
## , , Pot = 0
##
## Phos
## Nitro 0 1
## 0 51.43 54.33
## 1 63.77 57.93
##
## , , Pot = 1
##
## Phos
## Nitro 0 1
## 0 52.00 50.50
## 1 54.67 54.37
##-----------------------------------------------------------------------------
## aggregate.
## A aggragate funciona com uso de formula, além de poder ser usada como a
## tapply(). O resultado é em data.frame.
s <- with(npk,
aggregate(yield, list(Nitro=N, Phos=P, Pot=K), mean))
s
## Nitro Phos Pot x
## 1 0 0 0 51.43
## 2 1 0 0 63.77
## 3 0 1 0 54.33
## 4 1 1 0 57.93
## 5 0 0 1 52.00
## 6 1 0 1 54.67
## 7 0 1 1 50.50
## 8 1 1 1 54.37
s <- with(npk,
aggregate(cbind(Y=yield), list(Nitro=N, Phos=P, Pot=K), mean))
s
## Nitro Phos Pot Y
## 1 0 0 0 51.43
## 2 1 0 0 63.77
## 3 0 1 0 54.33
## 4 1 1 0 57.93
## 5 0 0 1 52.00
## 6 1 0 1 54.67
## 7 0 1 1 50.50
## 8 1 1 1 54.37
## Será obtido o mesmo, mas usando uma fórmula para representar o que se
## deseja.
s <- aggregate(yield~N+P+K, data=npk, mean)
s
## N P K yield
## 1 0 0 0 51.43
## 2 1 0 0 63.77
## 3 0 1 0 54.33
## 4 1 1 0 57.93
## 5 0 0 1 52.00
## 6 1 0 1 54.67
## 7 0 1 1 50.50
## 8 1 1 1 54.37
## Diferente da tapply, a aggregate pode ter mais de uma variáveis
## resposta. Por falta de outra variável resposta, será usando o log de
## yield.
s <- aggregate(cbind(y=yield, log.y=log(yield))~N+P+K, data=npk, mean)
s
## N P K y log.y
## 1 0 0 0 51.43 3.938
## 2 1 0 0 63.77 4.153
## 3 0 1 0 54.33 3.985
## 4 1 1 0 57.93 4.056
## 5 0 0 1 52.00 3.947
## 6 1 0 1 54.67 3.999
## 7 0 1 1 50.50 3.921
## 8 1 1 1 54.37 3.993
##-----------------------------------------------------------------------------
## by.
by(data=npk, INDICES=with(npk, N), FUN=nrow)
## with(npk, N): 0
## [1] 12
## -------------------------------------------------------------------
## with(npk, N): 1
## [1] 12
r <- with(npk, by(yield, INDICES=N, FUN=mean)); r
## N: 0
## [1] 52.07
## -------------------------------------------------------------------
## N: 1
## [1] 57.68
str(r)
## by [1:2(1d)] 52.1 57.7
## - attr(*, "dimnames")=List of 1
## ..$ N: chr [1:2] "0" "1"
## - attr(*, "call")= language by.default(data = yield, INDICES = N, FUN = mean)
c(is.list(r), is.array(r))
## [1] FALSE TRUE
r <- with(npk, by(yield, INDICES=list(N=N, P=P, K=K), FUN=mean)); r
## N: 0
## P: 0
## K: 0
## [1] 51.43
## -------------------------------------------------------------------
## N: 1
## P: 0
## K: 0
## [1] 63.77
## -------------------------------------------------------------------
## N: 0
## P: 1
## K: 0
## [1] 54.33
## -------------------------------------------------------------------
## N: 1
## P: 1
## K: 0
## [1] 57.93
## -------------------------------------------------------------------
## N: 0
## P: 0
## K: 1
## [1] 52
## -------------------------------------------------------------------
## N: 1
## P: 0
## K: 1
## [1] 54.67
## -------------------------------------------------------------------
## N: 0
## P: 1
## K: 1
## [1] 50.5
## -------------------------------------------------------------------
## N: 1
## P: 1
## K: 1
## [1] 54.37
str(r)
## by [1:2, 1:2, 1:2] 51.4 63.8 54.3 57.9 52 ...
## - attr(*, "dimnames")=List of 3
## ..$ N: chr [1:2] "0" "1"
## ..$ P: chr [1:2] "0" "1"
## ..$ K: chr [1:2] "0" "1"
## - attr(*, "call")= language by.default(data = yield, INDICES = list(N = N, P = P, K = K), FUN = mean)
c(is.list(r), is.array(r))
## [1] FALSE TRUE
class(r) ## Como é de classe by ele é mostrado de forma diferente.
## [1] "by"
unclass(r) ## Se a classe é removida, então é mostrado como array comum.
## , , K = 0
##
## P
## N 0 1
## 0 51.43 54.33
## 1 63.77 57.93
##
## , , K = 1
##
## P
## N 0 1
## 0 52.00 50.50
## 1 54.67 54.37
##
## attr(,"call")
## by.default(data = yield, INDICES = list(N = N, P = P, K = K),
## FUN = mean)
##-----------------------------------------------------------------------------
## Resumindo.
## As funções tapply, aggregate e by fazem tarefas por estrato. Em
## outras palavras, separam os valores em um (ou mais) vetores
## respeitando valores em outro (ou mais) e em seguida aplicam uma
## função. A diferença é como declarar e o que é retornado.
##-----------------------------------------------------------------------------
## apply.
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
str(Titanic)
## table [1:4, 1:2, 1:2, 1:2] 0 0 35 0 0 0 17 0 118 154 ...
## - attr(*, "dimnames")=List of 4
## ..$ Class : chr [1:4] "1st" "2nd" "3rd" "Crew"
## ..$ Sex : chr [1:2] "Male" "Female"
## ..$ Age : chr [1:2] "Child" "Adult"
## ..$ Survived: chr [1:2] "No" "Yes"
is.array(Titanic)
## [1] TRUE
dimnames(Titanic)
## $Class
## [1] "1st" "2nd" "3rd" "Crew"
##
## $Sex
## [1] "Male" "Female"
##
## $Age
## [1] "Child" "Adult"
##
## $Survived
## [1] "No" "Yes"
sum(Titanic[ ,1, , ]) ## Total de homens.
## [1] 1731
sum(Titanic[ ,2, , ]) ## Total de mulheres.
## [1] 470
apply(Titanic, MARGIN=2, sum) ## Totais das margens para Sex.
## Male Female
## 1731 470
apply(Titanic, MARGIN=1, sum) ## Para Class.
## 1st 2nd 3rd Crew
## 325 285 706 885
apply(Titanic, MARGIN=c(1,2), sum) ## Class e Sex.
## Sex
## Class Male Female
## 1st 180 145
## 2nd 179 106
## 3rd 510 196
## Crew 862 23
apply(Titanic, MARGIN=c(2,4), sum) ## Sex e Survived.
## Survived
## Sex No Yes
## Male 1364 367
## Female 126 344
apply(Titanic, MARGIN=c(3,4), sum) ## Age e Survived.
## Survived
## Age No Yes
## Child 52 57
## Adult 1438 654
str(HairEyeColor)
## table [1:4, 1:4, 1:2] 32 53 10 3 11 50 10 30 10 25 ...
## - attr(*, "dimnames")=List of 3
## ..$ Hair: chr [1:4] "Black" "Brown" "Red" "Blond"
## ..$ Eye : chr [1:4] "Brown" "Blue" "Hazel" "Green"
## ..$ Sex : chr [1:2] "Male" "Female"
dimnames(HairEyeColor)
## $Hair
## [1] "Black" "Brown" "Red" "Blond"
##
## $Eye
## [1] "Brown" "Blue" "Hazel" "Green"
##
## $Sex
## [1] "Male" "Female"
apply(HairEyeColor, MARGIN=1, sum) ## Por cor de cabelo.
## Black Brown Red Blond
## 108 286 71 127
apply(HairEyeColor, MARGIN=2, sum) ## Por cor de olhos.
## Brown Blue Hazel Green
## 220 215 93 64
apply(HairEyeColor, MARGIN=3, sum) ## Por cor de sexo.
## Male Female
## 279 313
##-----------------------------------------------------------------------------
## lapply e sapply.
is.list(rock)
## [1] TRUE
str(rock) ## Todas as colunas tem conteúdo numérico.
## 'data.frame': 48 obs. of 4 variables:
## $ area : int 4990 7002 7558 7352 7943 7979 9333 8209 8393 6425 ...
## $ peri : num 2792 3893 3931 3869 3949 ...
## $ shape: num 0.0903 0.1486 0.1833 0.1171 0.1224 ...
## $ perm : num 6.3 6.3 6.3 6.3 17.1 17.1 17.1 17.1 119 119 ...
lapply(rock, mean) ## Média
## $area
## [1] 7188
##
## $peri
## [1] 2682
##
## $shape
## [1] 0.2181
##
## $perm
## [1] 415.4
lapply(rock, range) ## Extremos.
## $area
## [1] 1016 12212
##
## $peri
## [1] 308.6 4864.2
##
## $shape
## [1] 0.09033 0.46413
##
## $perm
## [1] 6.3 1300.0
## Porque trata-se de um data.frame, dá pra usar apply também.
apply(rock, MARGIN=2, mean)
## area peri shape perm
## 7187.7292 2682.2119 0.2181 415.4500
apply(rock, MARGIN=2, range)
## area peri shape perm
## [1,] 1016 308.6 0.09033 6.3
## [2,] 12212 4864.2 0.46413 1300.0
sapply(rock, mean) ## Foi possível simplificar para um vetor.
## area peri shape perm
## 7187.7292 2682.2119 0.2181 415.4500
sapply(rock, range) ## Foi possível simplificar para uma matriz.
## area peri shape perm
## [1,] 1016 308.6 0.09033 6.3
## [2,] 12212 4864.2 0.46413 1300.0
str(iris)
## 'data.frame': 150 obs. of 5 variables:
## $ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
## $ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
## $ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
## $ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
## $ Species : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
lapply(iris, is.numeric) ## Quais colunas tem conteúdo numérico?
## $Sepal.Length
## [1] TRUE
##
## $Sepal.Width
## [1] TRUE
##
## $Petal.Length
## [1] TRUE
##
## $Petal.Width
## [1] TRUE
##
## $Species
## [1] FALSE
lapply(iris, class) ## Qual a classe?
## $Sepal.Length
## [1] "numeric"
##
## $Sepal.Width
## [1] "numeric"
##
## $Petal.Length
## [1] "numeric"
##
## $Petal.Width
## [1] "numeric"
##
## $Species
## [1] "factor"
## Também se pode usar apply pois iris é um data.frame.
apply(iris, MARGIN=2, is.numeric)
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## FALSE FALSE FALSE FALSE FALSE
sapply(iris, class) ## Foi possível simplificar.
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## "numeric" "numeric" "numeric" "numeric" "factor"
## Não foi possível simplificar.
sapply(iris, summary)
## $Sepal.Length
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 4.30 5.10 5.80 5.84 6.40 7.90
##
## $Sepal.Width
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 2.00 2.80 3.00 3.06 3.30 4.40
##
## $Petal.Length
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 1.00 1.60 4.35 3.76 5.10 6.90
##
## $Petal.Width
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 0.1 0.3 1.3 1.2 1.8 2.5
##
## $Species
## setosa versicolor virginica
## 50 50 50
## Separar as colunas que são númericas e então pedir o summary.
i <- sapply(iris, is.numeric); i
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## TRUE TRUE TRUE TRUE FALSE
sapply(iris[,i], summary) ## Simplificou.
## Sepal.Length Sepal.Width Petal.Length Petal.Width
## Min. 4.30 2.00 1.00 0.1
## 1st Qu. 5.10 2.80 1.60 0.3
## Median 5.80 3.00 4.35 1.3
## Mean 5.84 3.06 3.76 1.2
## 3rd Qu. 6.40 3.30 5.10 1.8
## Max. 7.90 4.40 6.90 2.5
##-----------------------------------------------------------------------------
## Para praticar, considere os conjuntos de dados disponíveis no pacote
## datasets do R. O nome dos objetos com dados estão listados abaixo.
a <- ls("package:datasets")
a
## [1] "ability.cov" "airmiles" "AirPassengers"
## [4] "airquality" "anscombe" "attenu"
## [7] "attitude" "austres" "beaver1"
## [10] "beaver2" "BJsales" "BJsales.lead"
## [13] "BOD" "cars" "ChickWeight"
## [16] "chickwts" "co2" "CO2"
## [19] "crimtab" "discoveries" "DNase"
## [22] "esoph" "euro" "euro.cross"
## [25] "eurodist" "EuStockMarkets" "faithful"
## [28] "fdeaths" "Formaldehyde" "freeny"
## [31] "freeny.x" "freeny.y" "HairEyeColor"
## [34] "Harman23.cor" "Harman74.cor" "Indometh"
## [37] "infert" "InsectSprays" "iris"
## [40] "iris3" "islands" "JohnsonJohnson"
## [43] "LakeHuron" "ldeaths" "lh"
## [46] "LifeCycleSavings" "Loblolly" "longley"
## [49] "lynx" "mdeaths" "morley"
## [52] "mtcars" "nhtemp" "Nile"
## [55] "nottem" "npk" "occupationalStatus"
## [58] "Orange" "OrchardSprays" "PlantGrowth"
## [61] "precip" "presidents" "pressure"
## [64] "Puromycin" "quakes" "randu"
## [67] "rivers" "rock" "Seatbelts"
## [70] "sleep" "stackloss" "stack.loss"
## [73] "stack.x" "state.abb" "state.area"
## [76] "state.center" "state.division" "state.name"
## [79] "state.region" "state.x77" "sunspot.month"
## [82] "sunspots" "sunspot.year" "swiss"
## [85] "Theoph" "Titanic" "ToothGrowth"
## [88] "treering" "trees" "UCBAdmissions"
## [91] "UKDriverDeaths" "UKgas" "USAccDeaths"
## [94] "USArrests" "USJudgeRatings" "USPersonalExpenditure"
## [97] "uspop" "VADeaths" "volcano"
## [100] "warpbreaks" "women" "WorldPhones"
## [103] "WWWusage"
## Alguns são vetores, outros arrays, outros data.frames e poucos são
## listas. Abaixo segue uma tabela com a relação. Dentre eles alguns são
## séries temporais onde valem as regras para vetor.
i <- sapply(a,
function(x){
x <- eval(parse(text=x))
oq <- c(is.vector(x), is.ts(x), is.array(x),
is.data.frame(x), is.list(x))
paste(c("V","S","A","D","L")[oq], collapse="")
})
res <- data.frame(objeto=a, classe=i, stringsAsFactors=FALSE)
res <- res[order(res$classe),]
rownames(res) <- NULL
## V: vetor; S: série; A: array/matriz; D: data.frame; L: lista.
by(res$objeto, res$classe, as.vector)
## res$classe:
## [1] "eurodist" "state.division" "state.region"
## -------------------------------------------------------------------
## res$classe: A
## [1] "crimtab" "euro.cross" "freeny.x"
## [4] "HairEyeColor" "iris3" "occupationalStatus"
## [7] "stack.x" "state.x77" "Titanic"
## [10] "UCBAdmissions" "USPersonalExpenditure" "VADeaths"
## [13] "volcano" "WorldPhones"
## -------------------------------------------------------------------
## res$classe: DL
## [1] "airquality" "anscombe" "attenu" "attitude"
## [5] "beaver1" "beaver2" "BOD" "cars"
## [9] "ChickWeight" "chickwts" "CO2" "DNase"
## [13] "esoph" "faithful" "Formaldehyde" "freeny"
## [17] "Indometh" "infert" "InsectSprays" "iris"
## [21] "LifeCycleSavings" "Loblolly" "longley" "morley"
## [25] "mtcars" "npk" "Orange" "OrchardSprays"
## [29] "PlantGrowth" "pressure" "Puromycin" "quakes"
## [33] "randu" "rock" "sleep" "stackloss"
## [37] "swiss" "Theoph" "ToothGrowth" "trees"
## [41] "USArrests" "USJudgeRatings" "warpbreaks" "women"
## -------------------------------------------------------------------
## res$classe: S
## [1] "airmiles" "AirPassengers" "austres" "BJsales" "BJsales.lead"
## [6] "co2" "discoveries" "fdeaths" "freeny.y" "JohnsonJohnson"
## [11] "LakeHuron" "ldeaths" "lh" "lynx" "mdeaths"
## [16] "nhtemp" "Nile" "nottem" "presidents" "sunspot.month"
## [21] "sunspots" "sunspot.year" "treering" "UKDriverDeaths" "UKgas"
## [26] "USAccDeaths" "uspop" "WWWusage"
## -------------------------------------------------------------------
## res$classe: SA
## [1] "EuStockMarkets" "Seatbelts"
## -------------------------------------------------------------------
## res$classe: V
## [1] "euro" "islands" "precip" "rivers" "stack.loss" "state.abb"
## [7] "state.area" "state.name"
## -------------------------------------------------------------------
## res$classe: VL
## [1] "ability.cov" "Harman23.cor" "Harman74.cor" "state.center"
*apply
.