mapa animado em R

9

todo mundo, desculpe pela perturbação, mas estou sendo bastante novo com r enfrentou uma dificuldade crucial: quero criar um mapa animado de Russin com mudanças no desemprego com anos diferentes, como. Na imagem você pode ver dados de um anoinsira a descrição da imagem aqui

require(sp)
require(maptools)

require(RColorBrewer)
require(rgdal)
 rus<-url("http://www.filefactory.com/file/4h1hb5c1cw7r/n/RUS_adm1_RData")
print(load(rus))


unempl <- read.delim2(file="C:\\unempl1.txt", header = TRUE, 
        sep = ";",quote = "", dec=",", stringsAsFactors=F)

gadm_names <-gadm$NAME_1
total <- length(gadm_names)
pb <- txtProgressBar(min = 0, max = total, style = 3) 

order <- vector()
for (i in 1:total){  

  order[i] <- agrep(gadm_names[i], unempl$region, 
                     max.distance = 0.2)[1]
 setTxtProgressBar(pb, i)               # update progress bar
}


col_no <- as.factor(as.numeric(cut(unempl$data[order],
                    c(0,2.5,5,7.5,10,15,100))))


levels(col_no) <- c("<2,5%", "2,5-5%", "5-7,5%",
                    "7,5-10%", "10-15%", ">15%")


gadm$col_no <- col_no
myPalette<-brewer.pal(6,"Purples")



proj4.str <- CRS("+init=epsg:3413 +lon_0=105")
gadm.prj <- spTransform(gadm, proj4.str)

spplot(gadm.prj, "col_no", col=grey(.9), col.regions=myPalette,
main="Unemployment in Russia by region")

O resultado que desejo obter é algo como animação aqui: http://spatial.ly/2011/02/mapping-londons-population-change-2011-2030/ No entanto, pesquisei bastante no Google, li vários temas em http://stackoverflow.com, incluindo o seguinte: Criando um filme a partir de uma série de gráficos em R , mas ainda não conseguia fazer a coisa certa.

Agradeço antecipadamente!

Eu vim com algo assim, alguém pode me dizer onde está o erro:

require(animation)
    require(sp)
    require(RColorBrewer) 
    require(classInt)     
require(rgdal)
 rus<-url("http://www.filefactory.com/file/4h1hb5c1cw7r/n/RUS_adm1_RData")
print(load(rus))




unempl1 <- read.delim2(file="C:\\unempl11.txt", header = TRUE, 
        sep = ";",quote = "", dec=",", stringsAsFactors=F)
unempl2<- read.delim2(file="C:\\unempl12.txt", header = TRUE, 
        sep = ";",quote = "", dec=",", stringsAsFactors=F)

gadm_names <-gadm$NAME_1


total <- length(gadm_names)
pb <- txtProgressBar(min = 0, max = total, style = 3) 

order <- vector()

for (i in 1:total){  

  order[i] <- agrep(gadm_names[i], unempl1$region, 
                     max.distance = 0.2)[1]
 setTxtProgressBar(pb, i)               # update progress bar
}


for (l in 1:total){  

  order[l] <- agrep(gadm_names[l], unempl2$region, 
                     max.distance = 0.2)[1]
 setTxtProgressBar(pb, i)               # update progress bar
}

col_no_1 <- as.factor(as.numeric(cut(unempl1$data[order],
                    c(0,2.5,5,7.5,10,15,100))))

col_no_2<- as.factor(as.numeric(cut(unempl2$data[order],
                    c(0,2.5,5,7.5,10,15,100))))
saveHTML(
      for(k in 1:2) {
        try<-get(paste("col_no_", k, sep = ""))

levels(try) <- c("<2,5%", "2,5-5%", "5-7,5%",
                    "7,5-10%", "10-15%", ">15%")


gadm$col_no <- try

myPalette<-brewer.pal(6,"Purples")



proj4.str <- CRS("+init=epsg:3413 +lon_0=105")
gadm.prj <- spTransform(gadm, proj4.str)

spplot(gadm.prj, "col_no", col=grey(.9), col.regions=myPalette,
main="Unemployment in Russia by region")
},img.name = "map", htmlfile = "unrus2.html")

Aqui estão os dados para poder reproduzir o código

Ruvin Rafailov
fonte
Re A edição: o que está errado com o código?
whuber
Como o seu exemplo não é reproduzível, é difícil solucionar problemas. Algumas coisas saltam para fora 1) você está aplicando uma transformação espacial em um loop, então você está fazendo isso repetidamente 2) você está criando um objeto chamado "try", que também é uma função R 3) você pode iterar através dos nomes reais das colunas, ou seja ., para (i em c ("Var1", "Var2")) a maneira como você o codifica atualmente é muito complicada 4) sua chamada ao spplot não está correta, você está passando um vetor sem sentido para ela.
Jeffrey Evans
Lamento muito por não ter entendido, mas esta é minha primeira experiência real com R, adicionei os dados na pergunta principal, se não incomodá-lo, por favor, sugere maneiras de melhorar como eu realmente correu ut de idéias
Ruvin Rafailov

Respostas:

4

Isto é tanto quanto eu vou. Você deve descobrir isso com base nesse código. Mais uma vez, como seu problema não é reproduzível, tive que criar dados fictícios para ilustrar a solução. Um aspecto estranho no uso do spplot é que, como ele usa a estrutura para criar o gráfico, você precisa criar um objeto e depois imprimi-lo. Caso contrário, você não receberá um enredo.

require(animation)
require(sp)
require(RColorBrewer) 
require(classInt)     
require(rgdal)

load(url("http://www.filefactory.com/file/4h1hb5c1cw7r/n/RUS_adm1_RData"))
closeAllConnections()

# Set color palette
myPalette <- brewer.pal(6,"Purples")

# Reproject data
gadm <- spTransform(gadm, CRS("+init=epsg:3413 +lon_0=105"))

# Create dummy unployment data with 10% change in gadm object 
gadm@data$uemp2000 <- runif(dim(gadm)[1],0,50)
gadm@data$uemp2001 <- gadm@data$uemp2000 + (gadm@data$uemp2000 * 0.10) 
gadm@data$uemp2002 <- gadm@data$uemp2001 + (gadm@data$uemp2001 * 0.10) 
gadm@data$uemp2003 <- gadm@data$uemp2002 + (gadm@data$uemp2002 * 0.10) 
gadm@data$uemp2004 <- gadm@data$uemp2003 + (gadm@data$uemp2003 * 0.10) 
gadm@data$uemp2005 <- gadm@data$uemp2004 + (gadm@data$uemp2004 * 0.10) 

# Coerce into factors with defined levels
for( i in c("uemp2000","uemp2001","uemp2002","uemp2003","uemp2004","uemp2005") ) {
  gadm@data[,i] <- as.factor(as.numeric(cut(gadm@data[,i], 
                             c(0,2.5,5,7.5,10,15,100)))) 
    levels(gadm@data[,i]) <- c("<2,5%", "2,5-5%", "5-7,5%",
                               "7,5-10%", "10-15%", ">15%")                          
    } 

saveHTML(
  for(i in c("uemp2000","uemp2001","uemp2002","uemp2003","uemp2004","uemp2005")) {
    sp.plot <- spplot(gadm, i, col=grey(.9), col.regions=myPalette,
                      main=paste("Unemployment in Russia", i, sep=" - ") )
      print( sp.plot )
},img.name = "map", htmlfile = "unrus2.html")
Jeffrey Evans
fonte
Obrigado! Vou tentar imediatamente. Apenas uma pergunta gadm @ data $ uemp2001 <- gadm @ data $ uemp2000 + (gadm @ data $ uemp2000 * 0.10) posso carregar aqui dados txt em vez de dados aleatórios, nenhuma solução de problemas ocorrerá?
Ruvin Rafailov
Sim, esse código está associado à criação de dados de exemplo. Você gostaria de usar seus próprios dados.
Jeffrey Evans
9

Dê uma olhada no pacote de animação . Uma das funções que vale a pena explorar, que não requer software de terceiros, é "saveHTML".

O uso da função "saveHTML" no pacote de animação é muito direto. Aqui está um código de exemplo em que eu crio uma animação de uma alteração aleatória da população. O argumento "expr" define a função de plotagem que você deseja passar para a animação. Como você pode ver no código abaixo, usei um loop for para plotar cada coluna simulada.

    require(animation)
    require(sp)
    require(RColorBrewer) 
    require(classInt)     

# Load your data and add random population change column
    load(url("http://www.gadm.org/data/rda/GBR_adm2.RData"))
      for( i in 1:10 ) {
        gadm@data[paste("Year",i, sep="")] <- runif(dim(gadm)[1],0,1) 
       }

# Create HTML animation using for loop for each simulated column    
    saveHTML(
      for(x in names(gadm@data)[19:28]) { 
      ani.options(interval = 0.5)  
       plotvar <- gadm@data[,x]
          nclr <- 9
         plotclr <- rev(brewer.pal(nclr,"BuPu"))
          cuts <- classIntervals(plotvar, style="fixed", 
               fixedBreaks=c(0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,1))
               colcode <- findColours(cuts, plotclr)
          plot(gadm, col=colcode, border=NA, ylim=c(bbox(gadm)[,1][2], bbox(gadm)[,2][2]),
            xlim=c(bbox(gadm)[,1][1], bbox(gadm)[,2][1]))
            text(min(bbox(gadm)[1]), min(bbox(gadm)[2]), paste("Population Change",x,sep=" "))
          box()
        legend("topleft", legend=c("0-10%","10-20%","20-30%","30-40%","40-50%",
               "50-60%","60-70%","70-80%","80-100%"),
                 fill=attr(colcode, "palette"), cex=0.6, bty="n")   
        ani.pause() 
        },
           img.name="RandPopChange", htmlfile="SimPopChange.html",
           single.opts = "'controls': ['first', 'previous', 'play', 'next', 'last', 'loop', 'speed'], 'delayMin': 0",      
            description=c("Random population change:"))  

Editei a postagem para fornecer um exemplo mais relevante com base em colunas de polígono.

Jeffrey Evans
fonte
Obrigado. No entanto, essa é a primeira coisa que eu realmente fiz, começando a explorar essa pergunta, mas ela não me deu o resultado, pois eu não conseguia entender qual expressão deveria ser um argumento.
Ruvin Rafailov
Acho que é apropriado, tentarei otimizar minhas necessidades assim que terminar a preparação dos dados. Muito obrigado, assim que funcionar, aceitarei uma resposta. E apenas a pergunta que surge imediatamente: é possível usar spplot aqui em vez de plot, você não tentou?
Ruvin Rafailov
Editei a questão principal para mostrar minhas idéias sobre o seu código, mas tenho certeza de que cometi vários erros, pois ele não funciona corretamente. Você pode ajudar com isso?
Ruvin Rafailov
7

A animação que você vinculou (abaixo) é uma imagem GIF animada .

insira a descrição da imagem aqui

É essencialmente uma série de imagens que são percorridas, o que cria o efeito de animação. Pense nisso como clicar em uma série de slides, um a cada segundo ou mais.

O que você precisa fazer para criar a animação é:

1) Crie cada 'quadro' individual que será mostrado.

2) Crie o próprio GIF. Existem vários sites que farão isso por você:

http://www.createagif.net/

http://makeagif.com/

A maioria desses sites permitirá que você controle o tamanho e a velocidade da animação.

A pergunta StackOverflow à qual você se vinculou deve fornecer tudo o que você precisa saber para executar esta tarefa em R. Observe que você deve instalar primeiro um pacote de terceiros.

EDIT : Abaixo está uma versão atualizada do código no link StackOverflow acima, pois parece haver um pouco de confusão.

jpeg("/tmp/foo%02d.jpg")
for (i in 1:5) {
  my.plot(i)
}      
make.mov <- function(){
     unlink("plot.mpg")
     system("convert -delay 0.5 plot*.jpg plot.mpg")
}

dev.off()

Este código acima pega cada um dos gráficos individuais que você criou no R e os converte em uma animação fazendo um loop sobre cada um e usando o ImageMagick , que você deve ter instalado.

Radar
fonte
Obrigado, mas eu sou um tipo tem uma necessidade de animação a ser feito dentro R sem outros sites e eu realmente não entendo como este código e ideia em obras stockoverflow, caso contrário eu teria nem mesmo pedir
Ruvin Rafailov
Acho que a resposta da troca de pilhas pode ser um pouco confusa porque a resposta dividiu o código com um bloco de texto. Vou editar minha resposta com uma versão atualizada desse código.
Radar
Obrigado pela atualização, mas ainda há vários problemas, que podem ser estúpidos e fáceis, mas infelizmente não tenho experiência em gerenciá-los. Se você não se importa, vou perguntar: 1) O que jpeg (...) significa neste código? como o Rstudio comete um erro de não conseguir abrir o arquivo 2) O Rstudio fala sobre a inexistência da função my.plot, embora tudo o que foi descoberto aqui esteja instalado. Talvez seja eu quem esteja operando de maneira errada, se puder, por favor, dê um conselho. Desde já, obrigado.
Ruvin Rafailov
2

Aqui está a resposta, graças a Oscar Perpiñán.

library(sp)
library(rgdal)
library(spacetime)
library(animation)
rus <- url("http://www.filefactory.com/file/4h1hb5c1cw7r/n/RUS_adm1_RData")
load(rus)
proj4.str <- CRS("+init=epsg:3413 +lon_0=105")
gadm.prj <- spTransform(gadm, proj4.str)
N <- nrow(gadm.prj)
pols <- geometry(gadm.prj)
nms<-gadm$NAME_1
vals1  <- read.csv2("C:\\unempl11.txt")
ord1 <- match(nms, vals1$region)
vals1 <- vals1[ord1,]

vals2 <- read.csv2("C:\\unempl12.txt")
ord2 <- match(nms, vals2$region)
vals2 <- vals2[ord2,]

nDays <- 2
tt <- seq(as.Date('2011-01-01'), by='year', length=nDays)
vals <- data.frame(unempl=rbind(vals1, vals2)[,-1])

gadmST <- STFDF(pols, time=tt, data=vals)



stplot(gadmST, animate=1, do.repeat=FALSE)

saveHTML(stplot(gadmST, animate=1, do.repeat=FALSE)
, img.name = "unemplan",  htmlfile = "unan.html")
Ruvin Rafailov
fonte
Ooh, eu gosto do uso da biblioteca de espaço-tempo!
Jeffrey Evans