Phylos.net
  • Índice
  • Sobre o Site
Programação

Programação com R

Post By Guilherme 23/01/2019 No Comments

Se você decidir ler esta seção mais tarde, pule para a seção Aquisição de Dados.

Esta seção apresenta uma formalização um pouco mais rigorosa dos conceitos do R como linguagem de programação. Em uma primeira leitura, para aqueles que ainda estão se familiarizando com a linguagem, ela pode ser pulada e lida mais tarde. Ela contém um pouco de repetição do material já visto, para fins de completeza.

Objetos

R é uma linguagem de programação de array, funcional e orientada a objeto. Todos os elementos de R, variáveis de dados e funções, são objetos. Não se pode acessar locais da memória diretamente e todos os objetos usados na execução de um programa são armazenados em memória RAM. Isso acaba tendo um peso importante quando se processa um grande volume de dados.

Linguagens de programação de arrays (também chamadas de linguagens vetoriais ou multidimensionais) são linguagens onde operações sobre objetos multidimensionais (vetores, matrizes, etc.) generalizam as operações sobre escalares de forma transparente. Elas permitem um código mais conciso e legível.

Todos os objetos possuem atributos que são meta-dados descrevendo suas características. Estes atributos podem ser listados com a função attributes() e definidos com a função attr(). Um desses atributos, bastante importante, é a classe de um objeto pois as funções de R usam essa informação para determinar como o objeto deve ser manipulado. A classe de
um objeto pode ser lida ou alterada com a função class()code>.

Existem os seguintes tipos de dados: Lógico ou booleano (logic), numérico (numeric), inteiro (integer), complexo (complex), caracter (character) e Raw.

Estes dados podem ser agrupados em estruturas de dados. Existem dois tipos fundamentais de estruturas: vetores atômicos e vetores genéricos. Vetores atômicos são matrizes de qualquer dimensão contendo um único tipo de dados. Vetores genéricos são também chamados de listas e são compostas por vetores atômicos. Listas são recursivas, no sentido de que podem conter outras listas.

Uma variável não precisa ser inicializada nem seu tipo declarado, sendo determinado implicitamente a partir do conteúdo do objeto. Seu tamanho é alterado dinamicamente.

Não existe o tipo “escalar” em R. Um escalar é simplesmente um vetor com um único elemento. Portanto a atribuição u <- 1 é apenas um atalho para u <- c(1).

Uma matriz é um vetor atômico acrescentado de um atributo dim com dois elementos (o número de linhas e de colunas). No exemplo seguinte, um vetor é transformado em uma matriz e depois recuperado como vetor:

> v <- 1:12
> print(v)
 [1]  1  2  3  4  5  6  7  8  9 10 11 12
> class(v)
[1] "integer"
> x <- c(1,2,3,4,5,6,7,8)
> class(x)
[1] "numeric"
> attr(v, "dim") <- c(2,6)
> print(v)
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    1    3    5    7    9   11
[2,]    2    4    6    8   10   12
> class(v)
[1] "matrix"
> # Um atributo arbitrário pode ser incluído
> attr(v, "nome") <- "minha matriz"

> attributes(v)
$dim
[1] 2 6
$nome
[1] "minha matriz"

> attr(v, "nome") <- NULL   # o atributo é removido
> attributes(v)
$dim
[1] 2 6
> # Um atributo pode ser alterado
> dim(v) <- c(3,4)
> print(v)
     [,1] [,2] [,3] [,4]
[1,]    1    4    7   10
[2,]    2    5    8   11
[3,]    3    6    9   12
> # Removido o atributo "dim" v volta a ser um vetor
> attr(v, "dim") <- NULL
> v
 [1]  1  2  3  4  5  6  7  8  9 10 11 12

A atribuição v <- 1:4 é idêntica à v <- c(1:4) e análoga, mas não idêntica à v <- c(1, 2, 3, 4). Nos dois primeiros casos o resultado é um vetor de inteiros. No terceiro temos um vetor numérico (de ponto flutuante).

Existem funções para a marcação de atributos: dim(), dimnames(), names(), row.names(), class() e tsp() (usado para a criação de séries temporais). Estas funções são preferíveis à simplesmente usar attr(vetor, "atributo") porque fazem um tratamento e análise dos parâmetros usados, emitindo notificações de erros mais detalhadas.

A igualdade entre objetos atômicos pode ser testada com o uso do operador ==, que verifica recursivamente a identidade de cada um dos elementos dos objetos comparados, ou da função identical(), que verifica a igualdade completa entre os dois objetos.

> a <- c(1,3,5); b <- c(1,3,5); c <- c(1,2,5)
> a==b
[1] TRUE TRUE TRUE
> a==c
[1]  TRUE FALSE  TRUE
> identical(a,b)
[1] TRUE
> identical(a,c)
[1] FALSE

Listas e Data Frames

As listas são coleções de vetores atômicos, não necessariamente de mesmo tipo. Elas são recursivas no sentido de que podem ter outras listas como seus elementos. Data frames são listas onde todos os vetores possuem o mesmo comprimento. Muitas funções recebem listas como argumentos ou retornam listas.

Para exemplificar vamos usar uma lista contendo as 5 primeiras observações do data frame warpbreaks, com 3 variáveis.

> quebras <- head(warpbreaks, n=5)
> quebras
  breaks wool tension
1     26    A       L
2     30    A       L
3     54    A       L
4     25    A       L
5     70    A       L

> # Usamos unclass() para ver seus componentes
> unclass(quebras)
$breaks
[1] 26 30 54 25 70

$wool
[1] A A A A A
Levels: A B

$tension
[1] L L L L L
Levels: L M H

attr(,"row.names")
[1] 1 2 3 4 5

> # Usamos attributes() para ver seus atributos
> attributes(quebras)
$names
[1] "breaks"  "wool"    "tension"

$row.names
[1] 1 2 3 4 5

$class
[1] "data.frame"

A igualdade entre objetos não atômicos não é implementado com o operador ==. Neste caso é necessário usar a função identical(), que verifica a igualdade completa entre os dois objetos.

> u <- list(v1=1,v2=2); v <- u
> v==u
Error in v == u : comparison of these types is not implemented
> identical(u,v)
[1] TRUE

> # identical testa a identidade entre quaisquer dois objetos:
> f <- function(x,y) x+y; g <- function(x,y) x+y
> identical(f,g)
[1] TRUE

A função unclass() retorna uma cópia de seu argumento sem seus atributos de classe. attributes() retorna uma lista com os atributos de seu argumento.

O que é o agrupamento k-means →

Agrupamento k-means é um método de agrupamento de dados muito utilizado em data mining que busca realizar uma partição de um número de observações em k grupos próximos de uma média comum. O resultado é o particionamento do espaço de dados nas chamadas células de Voronoi.

Selecionar partes de uma lista é uma operação importante em R. Para ilustrar algumas operações vamos usar o data frame iris que é uma lista contendo 5 vetores atômicos. Ela contém os campos (ou observações) Sepal.Length, Sepal.Width, Petal.Length, Petal.Width e Species. Relembrando, a função unclass(iris) exibe todos os valores em cada campo e seus atributos, separadamente. A função attributes(iris) exibe apenas os atributos. No exemplo abaixo aplicamos o agrupamento K-means usando a função kmeans(). Em seguida exploramos o objeto retornado que é uma lista.

> head(iris, n=2)
  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

> # Para selecionar apenas os 4 primeiros campos usamos iris[1:4]

> kGrupo <- kmeans(iris[1:4],3)
> typeof(kGrupo)    # para ver de que tipo é o objeto
[1] "list"
> length(kGrupo)    # kGrupo é uma lista com 9 elementos
[1] 9
> print(kGrupo)     # para listar todos os elementos do objeto
K-means clustering with 3 clusters of sizes 50, 38, 62

Cluster means:
  Sepal.Length Sepal.Width Petal.Length Petal.Width
1     5.006000    3.428000     1.462000    0.246000
2     6.850000    3.073684     5.742105    2.071053
3     5.901613    2.748387     4.393548    1.433871

Clustering vector:
  [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 [31] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 2 3 3 3 3 3 3 3
 [61] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 2 3 3 3 3 3 3 3 3 3 3 3 3
 [91] 3 3 3 3 3 3 3 3 3 3 2 3 2 2 2 2 3 2 2 2 2 2 2 3 3 2 2 2 2 3
[121] 2 3 2 3 2 2 3 3 2 2 2 2 2 3 2 2 2 2 3 2 2 2 3 2 2 2 3 2 2 3

Within cluster sum of squares by cluster:
[1] 15.15100 23.87947 39.82097
 (between_SS / total_SS =  88.4 %)

Available components:

[1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss" "betweenss"
[7] "size"         "iter"         "ifault"

> str(kGrupo)
List of 9
 $ cluster     : int [1:150] 1 1 1 1 1 1 1 1 1 1 ...
 $ centers     : num [1:3, 1:4] 5.01 6.85 5.9 3.43 3.07 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : chr [1:3] "1" "2" "3"
  .. ..$ : chr [1:4] "Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width"
 $ totss       : num 681
 $ withinss    : num [1:3] 15.2 23.9 39.8
 $ tot.withinss: num 78.9
 $ betweenss   : num 603
 $ size        : int [1:3] 50 38 62
 $ iter        : int 2
 $ ifault      : int 0
 - attr(*, "class")= chr "kmeans"

> # A lista contém os seguintes atributos
> attributes(kGrupo)
$names
[1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
[6] "betweenss"    "size"         "iter"         "ifault"

$class
[1] "kmeans"

> # sapply(objeto, class) exibe a classe de cada elemento na lista
> # A função sapply é tratada com maiores detalhes na próxima seção

> sapply(kGrupo, class)
     cluster      centers        totss     withinss tot.withinss    betweenss
   "integer"     "matrix"    "numeric"    "numeric"    "numeric"    "numeric"
        size         iter       ifault
   "integer"    "integer"    "integer"

> # Podemos visualizar simultaneamente o segundo elemento, "centers"
> # que fornece uma matriz com os valores do centro de cada agrupamento
> e size, 7º elemento, com o número de pontos em cada grupo

> kGrupo[c(2,7)]
$centers
  Sepal.Length Sepal.Width Petal.Length Petal.Width
1     5.006000    3.428000     1.462000    0.246000
2     6.850000    3.073684     5.742105    2.071053
3     5.901613    2.748387     4.393548    1.433871

$size
[1] 50 38 62

> # Para visualizar o segundo componente da lista kGrupo,
> # que é uma matriz, usamos
> kGrupo[2]
$centers
  Sepal.Length Sepal.Width Petal.Length Petal.Width
1     5.006000    3.428000     1.462000    0.246000
2     6.850000    3.073684     5.742105    2.071053
3     5.901613    2.748387     4.393548    1.433871

> # Para ver apenas os componentes desta matriz:
> kGrupo[[2]]
  Sepal.Length Sepal.Width Petal.Length Petal.Width
1     5.006000    3.428000     1.462000    0.246000
2     6.850000    3.073684     5.742105    2.071053
3     5.901613    2.748387     4.393548    1.433871

> # O mesmo resultado seria obtido por kGrupo$centers
> # Para listar a primeira linha da matriz
> kGrupo[[2]][,1]
       1        2        3
5.006000 6.850000 5.901613
> # Para listar a primeira coluna da matriz
> kGrupo[[2]][1,]
Sepal.Length  Sepal.Width Petal.Length  Petal.Width
       5.006        3.428        1.462        0.246
> # Para listar o primeiro elemento da primeira linha
> kGrupo[[2]][1,1]
[1] 5.006
> # que é o mesmo que kGrupo$centers[1,1]

Funções apply(), lapply(), sapply(), tapply()

A função apply() recebe como argumentos uma coleção de objetos (data frame, lista, vetor, etc.), o parâmetro MARGIN (que informa onde será aplicada a função) e uma função (qualquer função pode ser usada) e serve para executar alguma operação sobre essa coleção. Seu objetivo é principalmente o de evitar o uso de estruturas de loop. Ela tem a seguinte estrutura:

apply(X, MARGIN, FUN)
onde:
x: uma matriz ou array
MARGIN=n : onde n = 1 ou 2, definindo onde a função será aplicada:
se n=1: a função será aplicada nas linhas
se n=2: função aplicada nas colunas
se n=c(1,2): função aplicada nas linhas e colunas
FUN: define função a ser usada.
Podem ser funções internas (mean, median, sum, min, max, ...)
ou definidas pelo usuário
> # Usando a matriz v, já definida:
> print(v)
     [,1] [,2] [,3] [,4]
[1,]    1    4    7   10
[2,]    2    5    8   11
[3,]    3    6    9   12
> # A média das colunas
> apply(v,2,mean)
[1]  2  5  8 11
> # A soma das colunas
> apply(v,2,sum)
[1]  6 15 24 33
> minimosNasLinhas <- apply(v, 1, min)
> print(minimosNasLinhas)
[1] 1 2 3

A função lapply() recebe como argumentos uma coleção de objetos (data frame, lista, etc.) e uma função. Ela executa a função sobre todos os elementos da coleçao e retorna um objeto do tipo lista:

lapply(X, FUN)
onde:
X: vetor, lista, data frame, ...
FUN: Função a ser aplicada a cada elemento de X
Podem ser funções internas ou definidas pelo usuário

Para exemplificar aplicaremos a função tolower() para reduzir a letras minúsculas todas as palavras de um vetor de caracteres:

> partes <- c("RODAS","MOTOR","CARBURADOR","PNEUS")
> partesMinuscula <- lapply(partes, tolower)
> print(partesMinuscula)
[[1]]
[1] "rodas"
[[2]]
[1] "motor"
[[3]]
[1] "carburador"
[[4]]
[1] "pneus"

> # Esta lista pode ser convertida em um vetor usando-se unlist:
> partesMinuscula <- unlist(partesMinuscula)
> print(partesMinuscula)
[1] "rodas"      "motor"      "carburador" "pneus"

A função sapply() recebe como argumentos uma coleção de objetos (data frame, lista, etc.) e uma função. Ela age da mesma forma que lapply() mas retorna um vetor ou uma matriz:

sapply(X, FUN)
onde:
X: vetor, lista, data frame, ...
FUN: Função a ser aplicada a cada elemento de X
Podem ser funções internas ou definidas pelo usuário

Usaremos a função sapply() com o data frame cars que traz uma coleção de observações sobre velocidades e distâncias percorridas até repouso em cada velocidade em automóveis (em 1920) para encontrar os valores mínimos em cada coluna:

> # para ver a estrutura do data frame:
> str(cars)
 'data.frame':	50 obs. of  2 variables:
  $ speed: num  4 4 7 7 8 9 10 10 10 11 ...
  $ dist : num  2 10 4 22 16 10 18 26 34 17 ...
> lMinimos <- lapply(cars, max)
> sMinimos <- sapply(cars, max)
> print(lMinimos)
$speed
[1] 25
$dist
[1] 120

> print(sMinimos)
speed  dist
   25   120

O exemplo abaixo mostra o uso de lapply() e sapply() junto com uma função do usuário. Ela retorna os valores do data frame que estão abaixo da média em cada coluna. Neste caso elas retornam valores iguais, como se pode ver com o uso de identical():

> abaixoDaMedia <- function(x) {
                   media <- mean(x)
                   return(x[x < media])
                   }
> abaixoDaMedia(c(1,2,3,40,50))
 [1] 1 2 3
> minSapply <- sapply(cars, abaixoDaMedia)
> minLapply <- lapply(cars, abaixoDaMedia)
[1] TRUE
> minSapply
$speed
 [1]  4  4  7  7  8  9 10 10 10 11 11 12 12 12 12 13 13 13 13 14 14 14 14 15
[25] 15 15
$dist
 [1]  2 10  4 22 16 10 18 26 34 17 28 14 20 24 28 26 34 34 26 36 20 26 32 40
[25] 32 40 42 36 32

> # Os valores retornados são iguais (embora em objetos distintos):
> identical(minSapply, minLapply)
 [1] TRUE

A função tapply() calcula um valor usando uma função (mean, median, min, max, ...) sobre os dados de um objeto agrupados para cada valor de uma variável de fator dada.

tapply(X, INDEX, FUN = NULL)
onde:
X: um objeto, geralmente um vetor
INDEX: uma lista contendo fatores
FUN: a função a ser aplicada sobre os elementos de X

Para ilustrar o uso desta função vamos usar o data frame irisCalculamos primeiro a média dos comprimentos de sépalas para todas as espécies. Depois calculamos as médias para cada espécie em separado, setosa, versicolor, virginica.

Em seguida usamos o data frame mtcars para calcular o consumo médio dos carros, agrupados por número de cilindros (cyl = 4, 6, 8) e tipos de transmissão, am = 0 (automático), 1 = (manual).

> attach(iris)
> # O comprimento médio de todas as sépalas é
> mean(Sepal.Length)
[1] 5.843333
> # O comprimento médio das sépalas agrupadas por espécie:
> tapply(Sepal.Length, Species, mean)
    setosa versicolor  virginica
     5.006      5.936      6.588
> detach(iris)
> # Usando mtcars:
> attach(mtcars)
> # O consumo médio para todos os carros é
> mean(mtcars$mpg)
[1] 20.09062
> # O consumo médio dos carros, agrupados por cilindros e tipo de transmissão
> tapply(mpg, list(cyl, am), mean)
       0        1
4 22.900 28.07500
6 19.125 20.56667
8 15.050 15.40000

> # Para efeito de conferência, calculamos a media de mpg para am=0 e cyl=8
> L <- mtcars[cyl==8 & am==0,]
> # L contém apenas carros com  am=0 e cyl=8
> mean(L$mpg)
[1] 15.05
> detach(mtcars)

Lembramos que em R os índices começam em 1 e não 0, como em muitas outras linguagens.

Funções em R

Quase tudo em R é uma função. Até os operadores comuns são funções. A declaração 2 + 3 é, na verdade, uma forma sintética para "+"(2, 3).

> '+'(2,3)
[1] 5
> "*"(13, 9)
[1] 117

Em funções, parâmetros são passados por valor e não por referência. Isso significa que um objeto passado como parâmetro é copiado e a cópia passada para a função. O objeto original não é alterado. Além disso variáveis definidas no corpo de funções são locais e não podem ser usadas fora dela. Para tornar globa uma variável usada dentro de uma função podemos usar o operador de atribuição <<-. Considere, por exemplo, o código abaixo.

> f <- function(x) x <- x^2
> u <- c(1,2,3)
> v <- f(u)
> v
[1] 1 4 9
> u
[1] 1 2 3

> #  x é local à função
> print(x)
Error: object 'x' not found

> # Se necessário tornar x global fazemos

> f <- function(x) x <<- x^2
> v <- f(x)
> x
[1] 1 4 9

Ambientes (environments) e escopo

R armazena seus objetos em memória RAM dentro de ambientes ou environments. Um environment fica definido por uma lista que associa os nomes dos objetos nele carregados com seus valores. Eles existem principalmente para organizar estes objetos e a forma como R os encontra. Cada ambiente está ligado a um pai (um parent environment) fazendo com que os ambientes formem uma estrutura de árvore que termina no ambiente de nível mais alto que se chama R_EmptyEnv. Quando se inicia uma sessão o R se encontra no ambiente global, global environment, denominado R_GlobalEnv, também chamado de área de trabalkho do usuário. Quando o nome de um objeto é invocado em código o interpretador de R busca na lista do ambiente atual, que pode ser visto com a função environment(). Se não encontrado o nome é procurado no ambiente pai, e assim sucessivamente, até que o último é alcançado.

Um novo ambiente pode ser criado com a função new.env() e objetos dentro deste ambiente com a função assign(). Estes objetos podem ser recuperados através da função get() ou da notação ambiente$variavel. A função exists("variavel", envir = ambiente) verifica a existência de variavel no ambiente, enquanto os objetos em um ambiente são listados com ls(ambiente), como se ilustra abaixo:

> environment()                            # exibe ambiente atual

> var <- "este objeto está em Global Env"  # cria objeto em Global_Env
> novoEnv <- new.env()
> assign(var, "novo objeto em novoEnv", env=novoEnv)
> ls()
 [1] "novoEnv" "var"
> var
[1] "este objeto está em Global Env"
> get(var, env=novoEnv)
[1] "novo objeto em novoEnv"

> # A notação de "$" pode ser usada:
> novoEnv$var <- " outro valor para objeto em novoEnv"
> var
[1] " este objeto está em Global_env"
> novoEnv$var
[1] " outro valor para objeto em novoEnv"

> cat("var em global_env -->", var, "\nvar em novoEnv -->", novoEnv$var)
var em global_env --> este objeto está em Global Env
var em novoEnv --> novo objeto em novoEnv

> # Para ver o ambiente pai de novoEnv
> parent.env(novoEnv)

> novoEnv$x <- 1   $ insere nova variável no ambiente
> ls(envir=novoEnv)
[1] "var" "x"
> exists("x", envir = novoEnv)
[1] TRUE

A função abaixo percorre os ambientes de modo hierárquico à partir de R_GlobalEnv subindo para os pais até o último ambiente, R_EmptyEnv. Como este último não tem pai a função parent.env(a) resulta em erro, que interrompe o loop.

> exibirArvore <- function() {
           a <- environment()
           l <- 1
           repeat {
		       print(paste(strrep(" ", l), environmentName(a)))
			   a <- parent.env(a)
			   l <- l + 1
           }
  }
> exibirArvore()
[1] "  "
[1] "   R_GlobalEnv"
[1] "    tools:rstudio"
[1] "     package:stats"
[1] "      package:graphics"
[1] "       package:grDevices"
[1] "        package:utils"
[1] "         package:datasets"
[1] "          package:methods"
[1] "           Autoloads"
[1] "            base"
[1] "             R_EmptyEnv"
Error in parent.env(a) : the empty environment has no parent

Quando uma função é criada ela gera a criação de um ambiente próprio onde ficam as variáveis definidas em seu corpo. Para exemplificar a existência deste ambiente dedicado à definição da função criamos abaixo a função minhaFuncao(x) que retorna outra função que soma x ao seu argumento. O valor de x passado na definição da função não é alterado com uma definição de seu valor fora do corpo da função.

> f <- function() {
	  x <- 1
      print(environment())
      print(parent.env(environment()))
 }
> f()
<environment: 0xd31ee80>
<environment: R_GlobalEnv>

> minhaFuncao <- function(x) { function(y) x+y }
> h <- minhaFuncao(100)
> h(10)
[1] 110
> x <- 3
> h(2)
[1] 102    # internamente ao ambiente de h, x = 100
> # h vive no ambiente environment(h).
> # Neste ambiente existe apenas a variável:
> ls(environment(h))
[1] "x"

No caso acima o R criou o ambiente "0xd31ee80" que é filho de R_GlobalEnv. A variável x só existe dentro do ambiente da função.

Gerenciamento de memória

Como já mencionado, R mantém em memória RAM todos os seus objetos em uso, o que pode introduzir lentidão ou mesmo a impossibilidade de realizar alguma operação. Mensagens de erro sobre a insuficiência de espaço de memória indicam que o limite foi excedido. Este limite depende, é claro, do hardware usado, do sistema operacional e da compilação de R (a versão de 64 bits é mais eficiente). Para grandes volumes de dados é preciso procurar escrever um código eficiente para acelerar a execução com o eventual armazenando dados em meio externo para diminuir a sobrecarga na memória RAM e através do uso de rotinas estatísticas especializadas, escritas para maximar a eficiência no manipulação de dados.

Para uma programação mais eficiente é recomendável aplicar operações sobre vetores sempre que possível. As funções internas para manipulação vetores, matrizes e listas (tais como ifelse, colMeans e rowSums) são mais eficientes que loops (for e while). Matrizes usam menos recursos que data frames. No uso de read.table() para carregar dados externos para um data frame especifique as opções colClasses e nrows explicitamente, defina comment.char = "" e marque como NULL as colunas não necessárias. Ao ler dados externos para uma matriz, use a função scan().

Sempre que possível crie objetos com seu tamanho final ao invés de aumentar seu tamanho gradualmente, inserindo valores. Teste seu código usando uma amostra de dados menor para otimizá-lo e remover erros. Exclua objetos temporários ou desnecessários usando rm(objeto). Após a remoção use gc()) para iniciar a coleta de lixo. Use a função .ls.objects() para listar objetos no espaço de trabalho e encontrar o que ocupa mais memória e o que pode ser removido.

Use as funções Rprof(), summaryRprof() e system.time() para cronometrar o tempo e gasto em cada função e descobrir qual delas você deveria procurar otimizar. Rotinas externas compiladas podem ajudar a acelerar a execução do programa. Com o pacote Rcpp você pode transferir objetos de R para funções C++ e voltar quando são necessárias sub-rotinas otimizadas.

Para volumes de dados for muito grandes existem bibliotecas que incluem a funcionalidade de descarregar dados em bancos de dados externos ou arquivos binários simples e acessar parte deles. Alguns exemplos são:

Biblioteca Descrição
bigmemory grava e acessa matrizes em arquivos no disco.
ff fornece estruturas de dados que podem ser grabadas em disco, agindo como se permanecessem em RAM.
filehash implementa uma base de dados simples tipo chave-valor gravada em disco
ncdf, ncdf4 fornece interface para arquivos Unidata netCDF
RODBC, RMySQL, ROracle, RPostgreSQL, RSQLite acesso aos respectivos DBMS externos.

No que se refere à análise dos dados em grandes volumes estão disponíveis:

Pacotes biglm e speedglm: ajuste de modelos lineares lineares e generalizados para grandes conjuntos de dados de uma maneira eficiente em termos de memória. Incluem as funções lm() e glm() para lidar com grandes conjuntos de dados.

Diversos pacotes oferecem funções para operações sobre grandes matrizes produzidas pelo pacote bigmemory. biganalytics oferece agrupamento k-means, estatísticas de coluna e um wrapper para biglm. O pacote bigrf pode ser usado para se adequar às florestas de classificação e regressão. bigtabulate fornece funcionalidade table(), split() e tapply(). O pacote bigalgebra inclui funções avançadas da álgebra linear.

biglars oferece cálculo de regressão para conjuntos grande, usado juntamente com o pacote ff.

O pacote data.table introduz uma versão melhorada de um data frame, com métodos mais rápidos e eficientes para: agregação de dados; junções de intervalo; adição, modificação e exclusão de colunas por referência (sem cópias). Um data.table pode ser usado em qualquer função que receba um data frame como argumento.

Atualizando R e Bibliotecas

A atualização de R pode ser um pouco trabalhosa. Seguem algumas sugestões para usuários de Windows e Linux.

No Windows

Como eu não utilizo o Windows esta opção está mencionada aqui como uma sugestão, que eu não experimentei. Ela foi extraída da página R-statistics blog.

Uma forma possível e prática para atualizar a instalação do R no Windows consiste em usar a biblioteca installr. Para isso a bliblioteca deve ser instalada e executada de dentro do próprio console (ou do Rstudio, ou outra IDE).

> # instalando e carregando a biblioteca
> install.packages("installr")
> require(installr)
> updateR()

A função updateR() iniciará o processo de atualização, verificando se novas versões estão disponíveis. Se a versão instalada for a mais recente a função termina e retorna FALSE. Caso contrário será perguntado se o usuário deseja prosseguir, após a exibição de um sumário das novidades na versão.

Será oferecida ao usuário a opção de copiar as bibliotecas instaladas para a nova versão e, em seguida, a de atualizar estas bibliotecas.

Mac e Linux

A atualização pode ser feita manualmente usando pacotes no website da CRAN.

$ sudo apt-key adv --keyserver keyserver.ubuntu.com
--recv-keys E298A3A825C0D65DFD57CBB651716619E084DAB9
$ sudo add-apt-repository
'deb https://cloud.r-project.org/bin/linux/ubuntu bionic-cran35/'
$ sudo apt update
$ sudo apt install r-base

As linhas acima, para cada entrada no prompt, não devem ser quebradas.

Mais informações sobre instalações no Debian, Red Hat, SUSE e Ubuntu no site See CRAN-R Linux.

Para compilar à partir do código fonte consulte a página CRAN-R Installation and Administration.

Atualizando as bibliotecas

Tanto no Windows quanto no Linux para atualizar apenas as bibliotecas que foram instaladas com install.packages() basta usar, no console a função update.packages(). A função perguntará quais as bibliotecas você deseja atualizar. Para executar a atualização de todas elas, sem o prompt de consulta digite update.packages(ask = FALSE).

Além de update.packages() existem as funções old.packages() que informa quais as bibliotecas possuem versões mais atuais nos repositórios versões aplicáveis e new.packages() que procura por novas bibliotecas disponíveis e ainda não instaladas, oferecendo a opção de instalá-las.

Obs.: Pacotes instalados por devtools::install_github() não são atualizados pelos procedimento descritos. No Windows eles podem ser atualizados por installr.

No RStudio

Para atualizar o RStudio use o item de Menu: Help > Check for Updates. Para atualizar as bibliotecas use Menu: Tools > Check for Packages updates.




Aquisição de Dados

Deixe uma resposta Cancelar resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Navegação de Post

Previous Previous post: Aprofundando as técnicas sobre gráficos
Phylos.net | Designed by: Theme Freesia © 2019 WordPress
Top