Автоматизация производства карт больших кругов в R
Я взял некоторые вещи, которые я изучил в учебнике по составлению больших кругов Flowing Data, и объединил их с кодом, связанным в комментариях, чтобы предотвратить странные вещи, происходящие, когда R строит трансэкваториальные большие круги. Это дает мне это:
airports <- read.csv("/home/geoff/Desktop/DissertationData/airports.csv", header=TRUE)
flights <- read.csv("/home/geoff/Desktop/DissertationData/ATL.csv", header=TRUE, as.is=TRUE)
library(maps)
library(geosphere)
checkDateLine <- function(l){
n<-0
k<-length(l)
k<-k-1
for (j in 1:k){
n[j] <- l[j+1] - l[j]
}
n <- abs(n)
m<-max(n, rm.na=TRUE)
ifelse(m > 30, TRUE, FALSE)
}
clean.Inter <- function(p1, p2, n, addStartEnd){
inter <- gcIntermediate(p1, p2, n=n, addStartEnd=addStartEnd)
if (checkDateLine(inter[,1])){
m1 <- midPoint(p1, p2)
m1[,1] <- (m1[,1]+180)%%360 - 180
a1 <- antipode(m1)
l1 <- gcIntermediate(p1, a1, n=n, addStartEnd=addStartEnd)
l2 <- gcIntermediate(a1, p2, n=n, addStartEnd=addStartEnd)
l3 <- rbind(l1, l2)
l3
}
else{
inter
}
}
# Unique months
monthyear <- unique(flights$month)
# Color
pal <- colorRampPalette(c("#FFEA00", "#FF0043"))
colors <- pal(100)
for (i in 1:length(monthyear)) {
png(paste("monthyear", monthyear[i], ".png", sep=""), width=750, height=500)
map("world", col="#191919", fill=TRUE, bg="black", lwd=0.05)
fsub <- flights[flights$month == monthyear[i],]
fsub <- fsub[order(fsub$cnt),]
maxcnt <- max(fsub$cnt)
for (j in 1:length(fsub$month)) {
air1 <- airports[airports$iata == fsub[j,]$airport1,]
air2 <- airports[airports$iata == fsub[j,]$airport2,]
p1 <- c(air1[1,]$long, air1[1,]$lat)
p2 <- c(air2[1,]$long, air2[1,]$lat)
inter <- clean.Inter(p1,p2,n=100, addStartEnd=TRUE)
colindex <- round( (fsub[j,]$cnt / maxcnt) * length(colors) )
lines(inter, col=colors[colindex], lwd=1.0)
}
dev.off()
}
Я хотел бы автоматизировать производство карт для большого набора данных, содержащего все запланированные коммерческие маршруты - фиктивный образец - для совместного использования ATL и другими аэропортами в глобальной сети (airport.csv связан с публикацией Flowing Data). Предпочтительно, чтобы я выпускал одну карту в месяц, которую я использовал бы в качестве кадра в коротком видео, изображающем изменения в сетевом пространстве аэропорта Атланты.
Проблема: я не могу заставить цикл создавать более одного PNG - только из первого уникального месяца в каждом CSV - каждый раз, когда я запускаю его. Я вполне уверен, что код Аарона Хардина "ломает" автоматизацию, поскольку он используется в учебном пособии по потоковым данным. После трех дней возни с ним и в погоне за любыми практическими рекомендациями R, я понимаю, что мне просто не хватает отбросов, чтобы примирить одно с другим. Кто-нибудь может мне помочь автоматизировать процесс?
Для вас есть подтверждение диссертации!
1 ответ
Слишком много информации для комментария, поэтому я публикую ответ вместо этого. Вот что я думаю (и прочитал до конца, чтобы увидеть, в чем может быть проблема):
Я попытался запустить ваш код на исходных данных в учебнике по потоковым данным. (Очевидно, вы должны добавить столбец для ежемесячных данных, поэтому я просто добавил эту строку для рандомизации месяца:):
airports <- read.csv("http://datasets.flowingdata.com/tuts/maparcs/airports.csv",
header=TRUE)
flights <- read.csv("http://datasets.flowingdata.com/tuts/maparcs/flights.csv",
header=TRUE, as.is=TRUE)
# Add column with random data for month
flights$month <- sample(month.abb[1:4], nrow(flights), replace=TRUE)
Всякий раз, когда у меня есть цикл, выполнение которого занимает много времени, я обычно добавляю туда немного кода, который дает мне проверку прогресса. Используйте то, что вам по душе: print
, cat
, tcltk::tkProgressBar
, я использую message
:
for (i in 1:length(monthyear)) {
message(i)
#
# your code here
#
}
Во всяком случае, я тогда запустил ваш код. Все работает точно так, как должно. Поскольку я выбрал данные за четыре месяца, я получаю:
- Сообщение с текущей итерацией i печатается четыре раза
- четыре
png
участки, каждый с темной картой мира и ярко-желтыми линиями. Вот одна из четырех строк:
Итак, почему это работает на моей машине, а не на вашей?
Я могу только догадываться, но я предполагаю, что вы не установили рабочий каталог. Здесь нет setwd
в вашем коде, и вызов png
просто дает имя файла. Я подозреваю, что ваш код записывается в любой рабочий каталог вашей системы.
По умолчанию в моей установке, рабочий каталог:
getwd()
[1] "C:/Program Files/eclipse 3.7"
Чтобы решить эту проблему, выполните одно из следующих действий:
- использование
setwd()
установить рабочий каталог в верхней части вашего скрипта. - Или используйте полный путь и имя файла при вызове
png()