在R中使用地理数据时提高性能

在R中使用地理数据时提高性能,r,maps,geospatial,geo,R,Maps,Geospatial,Geo,我编写了以下脚本来生成用于绘制上述地图的原始数据。问题是,对于550000个数据点,在相对强大的机器上运行大约需要2小时。然而,我对R是新手,我想知道是否有任何优化的函数可以利用 基本思想是,给定一组地理空间数据,将该数据集拆分为200行,然后将每行拆分为一组正方形。然后计算行中每个正方形的值的总和。我在下面采用的方法是取一个正方形的“左上”点,计算正方形边缘的纬度/经度,排除所有不在这些边界内的点,然后对剩余的点求和。没有像PostGIS这样的解决方案,还有更好的方法吗 all.data &l

我编写了以下脚本来生成用于绘制上述地图的原始数据。问题是,对于550000个数据点,在相对强大的机器上运行大约需要2小时。然而,我对R是新手,我想知道是否有任何优化的函数可以利用

基本思想是,给定一组地理空间数据,将该数据集拆分为200行,然后将每行拆分为一组正方形。然后计算行中每个正方形的值的总和。我在下面采用的方法是取一个正方形的“左上”点,计算正方形边缘的纬度/经度,排除所有不在这些边界内的点,然后对剩余的点求和。没有像PostGIS这样的解决方案,还有更好的方法吗

all.data <- read.csv("FrederictonPropertyTaxDiffCleanedv3.csv", header=TRUE, 
stringsAsFactors=FALSE)
all.data$X <- as.numeric(all.data$X)
all.data$Y <- as.numeric(all.data$Y)

startEnd <- function(lats, lngs) {
  # Find the "upper left" (NW) and "bottom right" (SE) coordinates of a set of data.
  #
  # Args:
  #  lats: A list of latitude coordinates
  #  lngs: A list of longitude coordinates
  #
  # Returns: 
  #   A list of values corresponding to the northwest-most and southeast-most coordinates

  # Convert to real number and remove NA values
  lats <- na.omit(as.numeric(lats))
  lngs <- na.omit(as.numeric(lngs))

  topLat <- max(lats)
  topLng <- min(lngs)
  botLat <- min(lats)
  botLng <- max(lngs)

  return(c(topLat, topLng, botLat, botLng))
}

startEndVals <- startEnd(all.data$Y, all.data$X)
startLat <- startEndVals[1]
endLat <- startEndVals[3]
startLng <- startEndVals[2]
endLng <- startEndVals[4]

num_intervals = 200.0
interval <- (startEndVals[1] - startEndVals[3]) / num_intervals

# testLng <- -66.6462379307115
# testLat <- 45.9581234392

# Prepare the data to be sent in
data <- all.data[,c("Y", "X", "levy2014_ha")]

sumInsideSquare <- function(pointLat, pointLng, interval, data) {
  # Sum all the values that fall within a square on a map given a point,
  # an interval of the map, and data that contains lat, lng and the values
  # of interest

  colnames(data) <- c("lat", "lng", "value")

  # Data east of point
  data <- data[data$lng > pointLng,] 
  # Data west of point + interval
  data <- data[data$lng < pointLng + interval,] 
  # Data north of point + interval (down)
  data <- data[data$lat > pointLat - interval,]
  # Data south of point
  data <- data[data$lat < pointLat, ]

  # Clean remaining data
  data <- na.omit(data)
  return(sum(data$value))
}

# Debugging
# squareSumTemp <- sumInsideSquare(testLat, testLng, interval, data)

# Given a start longitude and an end longitude, calculate an array of values
# corresponding to the sums for that latitude

calcSumLat <- function(startLng, endLng, lat, interval, data) {
  row <- c()
  lng <- startLng
  while (lng < endLng) {
    row <- c(row, sumInsideSquare(lat, lng, interval, data))
    lng <- lng + interval
  }
  return(row)
}

# Debugging
# rowTemp <- calcSumLat(startLng, endLng, testLat, interval, data)
# write.csv(rowTemp, file = "Temp.csv", row.names = FALSE)

# Get each line of data to plot
lat <- startLat
rowCount <- 1
all.sums <- list()
while (lat > endLat) {
  col <- calcSumLat(startLng, endLng, lat, interval, data)
  all.sums[[as.character(rowCount)]] <- col
  lat <- lat - interval
  rowCount <- rowCount + 1
}

# Convert to data frame
all.sums.frame <- data.frame(all.sums)

# Save to disk so I don't have to run it again
write.csv(all.sums.frame, file = "Levy2014Sums200.csv", row.names = FALSE)

all.data最终自己找到了解决方案。关键是使用foreach软件包和doParallel软件包,这样它就可以利用我计算机上的所有内核。这里有一个很好的指南:

您是否尝试过使用
Rprof
分析您的代码,以找出花费时间最多的地方?直到现在才知道Rprof-将查看它!使用RProf很明显,瓶颈在于sumInsideSquares函数。我重新编写了这个函数,以便所有的数据帧分割都在一行上进行,从而将时间缩短了一半。不过,仍然需要很长时间才能运行,所以我需要进一步优化它。我可能会开始研究R中的多线程,因为这将是它的主要候选者。