Feeds:
Posts
Comentários

There at least two functions to build a surface plot in R, persp() and wireframe(). Here I show a documented code to build a surface with wireframe() and how to define the color of each surface.

The code below generates this graph

# Required packages
library(lattice)

# Example: data format
#         x       y        z      group
# 1      1.0     0.5    1.5000    data1
# 2      1.0     0.6    1.6000    data1
# 3      1.0     0.7    1.7000    data1
# 4      1.0     0.8    1.8000    data1
# 90     1.4     0.6    6.9712    data2
# 91     1.4     0.7    7.0817    data2
# 92     1.4     0.8    7.2512    data2
# 93     1.4     0.9    7.4977    data2

# Generating the parameters
rm(list=ls())
x <- seq(1,2,0.2);
y <- seq(0.5,1.5,0.1);

data1 <- matrix(0,nrow=length(x)*length(y),ncol=3);
data2 <- matrix(0,nrow=length(x)*length(y),ncol=3);

n <- 0;
j <- 1;
while(j<=length(x)){
   for (k in 1:length(y)){
       data1[k+n,1] <- x[j];
       data1[k+n,2] <- y[k];
       data1[k+n,3] <- x[j]^4 + y[k];

       data2[k+n,1] <- x[j];
       data2[k+n,2] <- y[k];
       data2[k+n,3] <- x[j]^4 + y[k]^4 + 3;
   }
   n <- n+length(y);
   j <- j+1;
}
rm(x,y,j,n,k)

# Arranging data into a data frame
data1_2 <-as.data.frame(rbind(data1,data2));
colnames(data1_2) <- c("x","y","z");
data1_2$group <- gl(2, nrow(data1_2)/2, labels=c("data1", "data2"))
rm(data1,data2)

# Plotting data as a surface
wireframe(z~x*y,data=data1_2,groups=group,

      # Naming labels and Axis
      main =list(label="Plot of 2 Surfaces",cex=2,distance=5),
      zlab=list(rot=90,label = "Z",cex=2),
      xlab=list(label = "X",cex=2),
      ylab=list(label = "Y",cex=2),

      # Coloring the groups
      col.groups=c(rgb(red=255,green=153,blue=102,
                       alpha=200,maxColorValue=255),  # Orange
                   rgb(red=207,green=231,blue=245,
                       alpha=200,maxColorValue=255)), # Blue

      # Coloring the grids
      col=c(rgb(red=0,green=0,blue=0,alpha=50,maxColorValue=255),
            rgb(red=0,green=0,blue=0,alpha=50,maxColorValue=255)),

      aspect=c(1,1), # y-size/x-size and z-size/x-size
      screen = list(z=40,y=0,x=-80)); # axis rotation

O R é uma linguagem e ambiente de computação gratuíto com toneladas de pacotes estatísticos e outros tantos. É uma ferramenta importante para análise dados e construção de modelos. Instalar o R no Ubuntu requer algumas etapas.

A primeira é adicionar um repositório que contenha os arquivos de instalação do R. Visitando a página oficial do R, http://www.r-project.org/ , é possível encotrar vários endereços de repositórios espalhados pelo mundo. A vantagem de ter o endereço de um repositório é que o Ubuntu automaticamente reconhece e instala eventuais atualizações. Então, uma maneira de fazê-lo é abrir o Update Manager (figura abaixo) e clicar em settings. Na aba de outros softwares, clicar em adicionar e digitar o seguinte endereço:

deb http://<my.favorite.cran.mirror>/bin/linux/ubuntu precise/

No lugar do <my.favorite.cran.mirror>, substitua pelo repositório. Eu escolhi o repositório do LEB da Universidade de São Paulo http://www.vps.fmvz.usp.br/CRAN/ , pois é próximo e tão atualizado quanto os demais. Poderia ser o da Universidade da Califórnia, cran.stat.ucla.edu, por exemplo, o resultado final é:

deb http://cran.stat.ucla.edu/bin/linux/ubuntu precise/

Agora é fechar a janela de settings e clicar em check. Por vezes, aparece um erro de chave pública e a atualização do repositório que acabamos de adicionar não é concluída. Supondo que foi utilizado o endereço da UCLA, o erro seria esse aqui:

W: GPG error: http://cran.stat.ucla.edu precise/ Release: The following signatures couldn’t be verified because the public key is not available: NO_PUBKEY 51716619E084DAB9 .

Para corrigir isso é necessário recuperar uma chave. Para o caso do espelho da ucla, temos que digitar no terminal os comandos:

gpg –recv-key 51716619E084DAB9
gpg –export –armor 51716619E084DAB9 | sudo apt-key add –

O número 51716619E084DAB9 é extraído da mensagem de erro, ou seja, outro repositório tem outra chave.

Por fim, é só abrir o Ubuntu Software Center e instalar o R. As atualizações serão automáticas.

Por vezes é necessário inserir uma linha num conjunto de dados, então, aqui vai um comando simples . Considere um conjunto de dados com 6 colunas, deseja-se inserir uma nova linha com informações preenchidas, então, uma opção é: 

proc sql;
INSERT INTO libname.dados
VALUES (1234 1410 147 "47814" "006" 5631);
SELECT * 
FROM libname.dados;
quit;

Existem diferentes símbolos para registrar a posição decimal de um número, por exemplo, no Brasil a marca decimal é uma vírgula, no México é o ponto. A escolha da marca decimal (ponto, vírgula ou outra coisa qualquer) de um número não deveria ser um grande obstáculo para quem trabalha com números, contudo, alguns softwares tem por default uma ou outra marca, é o caso do SAS, que usa o ponto. Então, aqui vai uma dica para converter a vírgula em ponto sem muita complicação, basta usar este pedaço de código:

x=input(translate(A,’.’,’,’),32.);  /* translate (variável; ‘PARA’ ; ‘DE’ )*/

Mapas com R e Google

É interessante, por vezes, apontar num mapa a posição de um ou vários objetos. Com o pacote RgoogleMaps é possível fazer isso e ter mapas com look de Google Map, ou seja, mapas de terrenos, estradas, híbridos… Abaixo, vou colocar um exemplo de como fazer isso.

Primeiro, é importante ter as coordenadas (latitude e longitude) do objeto para adiciona-lo no mapa. É aí que entra o pacote dismo. Existe uma função deste pacote que usa o endereço e recupera a latitude e longitude, na verdade, essa função é um wrapper para outra função do RgoogleMaps que usa um API do google para recuperar os dados. Depois disso, o resto é RgoogleMaps puro

# carrega o pacote dismo e RgoogleMaps
 library('dismo')
 library('RgoogleMaps')
 library('XML')

# recupera as coordenadas de um endereço
# Usei o endereço próximo do LEB-USP  e do IB-USP como exemplos (onde eu faço e fiz as pós)
 coordenadas<-geocode(c('Rua Professor Gabriel Silvestre Teixeira de Carvalho, Sao Paulo','Rua do Matao 321, 05508090, Sao Paulo'))

# Organizando os marcadores, aqui tem umas precauções
 mymarkers <-cbind.data.frame( lat= as.vector(t(coordenadas[,'latitude'])), lon= as.vector(t(coordenadas[,'longitude'])), color= c('green','green'), size=c('big','big'),label=c('L','I'))

# Determina o range/tamanho do mapa
 bBox <- qbbox(lat = coordenadas[,'latitude'], lon = coordenadas[,'longitude'])

# finalmente, pegando o mapa
 mapaPlot <- GetMap.bbox(bBox$lonR, bBox$latR, maptype="hybrid", format='jpg', destfile='viva.jpg', markers=mymarkers)

 O resultado é a imagem abaixo, legal, né?

 

Infelizmente, há um limite para o número de marcadores que podemos chamar nas funções getMap(), por conta do ERRO 414, porém o RgoogleMaps permite de plotar centenas de pontos em cima de um mapa, por exemplo, usando a função PlotOnStaticMap().

Computação paralela é escrever um programa que executa tarefas de forma simultânea e não de maneira sequencial. Como isso é possível? Muitas rotinas de um programa podem ser divididas, cada pedaço dessa rotina pode ser processada por uma unidade de processamento (CPU) diferente  e ao mesmo tempo. Essas CPUs podem estar num computador (multicore)  ou por CPUs espalhados numa rede de computadores.

Qual é a vantagem? A vantagem é  na velocidade que essa rotina é processada. Se o computador tem 4 núcleos, isso significa que o programa pode ter um aumento de velocidade próximo de 4 vezes. Qual é a desvantagem? O código fica mais complicado, mais cuidado deve ser tomado.

O snowfall é um pacote do R que facilita um pouco o trabalho na hora de escrever um script que executa algum cálculo paralelamente. Abaixo um exemplo simples, comentado.

# example of parallel computing

# Carrega o pacote snowfall
library(snowfall);

# Inicial o snowfall com configuração desejada, dois Cpus, no caso
sfInit(parallel=TRUE,cpus=2);

# variables
listSize <- 100;
scale <- 0.1;

# wrapper é a função que será executada paralelamente
wrapper <- function(iteration){
  numbersList <- scale*iteration
  return(numbersList);
}

# Export global objects para as Cpus
sfExport(list=as.vector(c("scale")));

# divide a tarefa em 2, uma lista para cada processador
jobSplit<-sfClusterSplit(seq(1:listSize));

# entrega o jobSplit para a função wrapper através do sfClusterApply
preListOfNumbers<-sfClusterApply(jobSplit,wrapper);

# como a sfClusterApply devolve uma lista, então a gente unlista
numbersList<-unlist(preListOfNumbers,recursive=FALSE);

# stopping snowfall and Removes all variables
sfRemoveAll();
sfStop();

Note que esse exemplo é simples e existe outros pacotes que ajudam no processamento paralelo. É isso!

Existe diferentes  maneiras de organizar informações, usar listas é uma delas, pois podem armazer diferentes tipos de dados. Por exemplo, suponha que exista três fazendas (A, B e C) e cada uma tem um nome, número de animais e a evolução do número de animais contaminados nos dois primeiros meses). Pode-se criar uma lista que armazena estas informações, uma maneira de fazer é a seguinte:

fazendas<-list(A=list(name="Primavera",animal=100,doentes=c(1,6,6)),
               B=list(name="Outono",animal=50,doentes=c(1,5,1)),
               C=list(name="Verão",animal=500,doentes=c(0,3,50)));

Note que é criado uma lista dentro de outra lista, ou seja, uma lista de fazenda (A,B e C) e cada fazenda tem uma lista de características (nome, animal, doentes), sendo cada característica é de formato diferente (string, número e vetor).

Acessar essa lista pode ser feito de duas maneiras, suponha que deseja-se recuperar as informações da fazenda C:

fazendas[[3]] # uma maneira
fazendas$C    # outra maneira

O resultado é:

> fazendas$C
$name
[1] "Verão"
$animal
[1] 500
$doentes
[1]  0  3 50

Ou o objetivo seja recuperar o número de animais doentes da fazenda B no segundo mês:

fazendas[[2]][[3]][2] # uma maneira
fazendas$B$doentes[3] # outra maneira

A lista não é o objeto de manipulado veloz, mas é uma maneira bem organizada de ter um banco de informações.

Assume-se que em redes existe a formação de comunidades que são definidas como grupo de vértices que tem uma grande densidade de arestas entre eles e com pouca densidade de arestas entre groupos (Newman, The structure and function of complex networks).

É possível visualizar e identificar as comunidades com o R e o pacote igraph. O código abaixo (criado com uma força do pessoal do LEB-USP, que tem familiaridade com o assunto) é uma função bem simples, com a qual se pode criar uma rede com atração preferencial e depois visualizar as comunidades, separadas por cor e letra- é usado o algorítmo walktrap para identificar as comunidades. Ainda, adota-se a terminologia pequena, moderada e grande, para atração preferencial dos vértices.

# Loads the tibrary
library(igraph)
communityD<-function(nodes,alpha){

  # it creates a network
  g<-barabasi.game(n=nodes,power=alpha,m=2,directed=FALSE);

  # it tries to identify densily connected vertices
  gWT<-walktrap.community(g,steps=5);

  # adding colours & labels to community members
  indices<-gWT$membership+1;
  col<-rainbow(max(indices));
  V(g)$color<-col[indices];
  V(g)$label<-intToUtf8((indices+64),multiple=TRUE);

  # it creates layout and plots the graph
  gLayout<-layout.fruchterman.reingold(g);
  plot(g,layout=gLayout,vertex.size=16);
  title('Barabási game/ Comunidades');
}

Este slideshow necessita de JavaScript.

Uma rede é  constutuída de vértices e arestas. Com estes elementos é possível descrever redes reais, por exemplo, redes genéticas na qual os vértices representam genes, proteínas e as arestas representam as interações químicas, ou ainda, nas ciências sociais, os vértices representam  indivíduos e as arestas a intereção entre eles. Uma vez que a rede é construída, é possível estudar o seu comportamento e suas características.

Muitas redes reais apresentam uma característica em comum, a sua topologia é livre de escala, que pode ser traduzida da seguinte maneira: a probabilidade de um vértice estar ligado a outro vértice decai exponencialmente, ou melhor, muitos vértices estão ligados com poucos vértices e poucos vértices interagem com um número muito grande de vértices. Em termos matemáticos, isso é modelado por uma lei de potência negativa com o expoente entre 1 e 3. Só para se ter uma idéia do que isso significa, é como se a maioria das pessoas tivessem por volta de 30 amigos e algumas pessoas (os mais populares) terem dezenas de milhares de amigos (é só uma exemplo fictício).

Não se tem muitas pistas a respeito do motivo que leva redes reais a ter essa característica. Entretanto, em um report na science de 1999, Barabási sugere que isso pode ser atribuído ao preferential attachment. A idéia é mais ou menos a seguinte, suponha que poucas pessoas morem num bairro qualquer e são amigas entre si. Novos moradores chegam ao bairro, então, de acordo com a teoria da atração preferencial, esses novos moradores tem uma maior probabilidade de fazer contato com os mais antigos no bairro, seja porque eles conhecem mais detalhes da vida no bairro ou por qualquer outro motivo.

A atração preferêncial rendeu 9000 citações (mais ou menos) e um livro (Linked , fala mais sobre o assunto sem uma linguagem técnica), pois é capaz de construir redes com características de redes reais livres de escala. Mas, ainda assim, não explica alguns fenômenos.

De qualquer maneira, é possível, com o pacote igraph no R, gerar grafos (redes) usando um algorítmo baseado nessa teoria, lá vai um exemplo (no final, o código gera uma visualização, com histograma e rede no mesmo plot, um subplot, com sugestão do pessoal do LEB-USP):

# Carrega o pacote igraph
library(igraph)
# cria a rede: n= número de nós, power= "poder de atração", m=número de links cada nó faz quando entra na rede
g<-barabasi.game(n=50,power=1,m=2,directed=FALSE);
# it creates layout and plots the graph
gLayout<-layout.fruchterman.reingold(g);
X11() # evita problemas no RStudio criando uma nova janela
plot(g,layout=gLayout,vertex.size=16);
title('Barabási game');
par(fig=c(2/3,1,2/3,1), new=T)
hist(degree(g), main="")
title('Histograma');

As imagens são geradas para um mesmo número de vértices (50) e  de arestas (98), mudando apenas o alpha, relacionado com a atração preferencial (adota-se a terminologia pequena, moderada e grande, relativo aos próprios alfas).

Este slideshow necessita de JavaScript.

Note, que os histogramas mostram a distribuição do degree (grau, número de links que cada nó tem). Não fiz a as contas para mostra se são realmente livres de escala ou não, mas dá para perceber que com o aumento da atração preferencial, há nós com muito mais links que os outros.

Pode ser muito util as variáveis assumirem nomes que são entradas de teclado ou que nomes de variáveis sejam transformadas em strings. Num post anterior, eu mostrei como converter uma string num nome de variável com o  comando assign(). Agora o contrário, converter o nome de uma variável numa string, lá vai:

Suponha a variável teste:

teste<-seq(2,10,by=2);

Caso se faça necessário, posso armazenar o nome dessa variável como string:

a<-deparse(substitute(teste))

e pornto!