在R中自动化制作大圆地图

8

我将在流动数据 大圆映射教程 中学到的一些内容与评论中链接的代码结合起来,以防止 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()
}

我希望自动化制作地图,用于包含所有预定商业路线的大型数据集 — dummy sample — 与全球网络中的ATL和其他机场共享(airports.csv链接在Flowing Data帖子中)。最好每月生成一张地图,我将使用它作为短视频中的一个帧,描述亚特兰大机场网络空间的变化。 问题:每次运行循环时,我无法获得比一个PNG更多的内容 —— 仅来自每个CSV中第一个唯一月份。我相当确定Aaron Hardin的代码在Flowing Data教程中使用时“破坏”了自动化。经过三天的折腾和追寻任何相关的R how-to,我意识到我简单地缺乏调和两者的能力。有人能帮我自动化这个过程吗?
你会得到一份论文致谢!

1
你展示了很多代码。试图做一个最小的例子,但仍然不能正常工作。例如,做一个简单的循环,绘制一系列非常简单的图表。更简单的方法是,让每个循环只打印imonthyear [i]的值。我敢打赌,在这个过程中你会发现错误。如果没有,请发布最小的例子,有人将能够帮助你。 - Andrie
您可以使用 pdf() 作为输出格式,并使用 monthyear 作为主标签,这样你就不必在循环中每次打开和关闭文件输出连接。 - mzuba
@mzuba 是的,但这样你只会得到一个PDF文件,而不是每个图形的文件。 - Andrie
1个回答

13

这些信息太多了,评论里说不过来,所以我发了一个回答。以下是我的想法(请读完,看看可能的问题是什么):

我在Flowing Data教程中使用原始数据运行了您的代码。(显然您需要添加一个月度数据列,所以我只是添加了一行代码来随机生成月份):

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绘图。这是其中一个图的截图:

enter image description here

无论如何,为什么它能在我的机器上运行而在你的机器上不能呢?
我只能猜测,但我猜测你没有设置工作目录。你的代码中没有setwd,而是直接给出了png的文件名。我怀疑你的代码被写入到你系统中任意的工作目录。
在我的安装中,默认工作目录为:
getwd()
[1] "C:/Program Files/eclipse 3.7"
为了解决这个问题,请执行以下任一操作:
  1. 使用 setwd() 在你的脚本顶部设置你的工作目录。
  2. 或在调用 png() 时使用完整的路径和文件名。

这看起来会是一个很大的帮助。我今天还没有时间去处理这个项目,但我会在处理时告诉你进展如何。谢谢。 - gpe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接