【问题标题】:Spatial aggregation with a group by具有分组依据的空间聚合
【发布时间】:2015-12-13 14:49:36
【问题描述】:

我正在尝试基于空间计算分组平均值 聚合。

我有两个 shapefile:人口普查区和病房。病房有价值 我想对每个人口普查区按一个因子进行平均。

这里是 shapfiles:

library(dplyr)
library(rgeos)
library(rgdal)
# Census tracts
download.file("http://www12.statcan.gc.ca/census-recensement/2011/geo/bound-limit/files-fichiers/gct_000b11a_e.zip", 
    destfile = "gct_000a11a_e.zip")
unzip("gct_000a11a_e.zip", exdir="tracts") # corrected typo
census_tracts <- readOGR(dsn = "tracts", layer = "gct_000b11a_e") %>%
  spTransform(CRS('+init=epsg:4326'))

# Wards
download.file("http://opendata.toronto.ca/gcc/voting_subdivision_2010_wgs84.zip",
                destfile = "subdivisions_2010.zip")
unzip("subdivisions_2010.zip", exdir="wards")
wards <- readOGR(dsn = "wards", layer = "VOTING_SUBDIVISION_2010_WGS84") %>%
  spTransform(proj4string(census_tracts))

然后我将人口普查区划分为仅选区中的人口普查区:

census_tracts_in_wards <- census_tracts[wards, ]

我有每个病房的数据,具有两级因子:

df <- expand.grid(AREA_ID = wards$AREA_ID, factor = as.factor(letters[1:2]))
df$value <- rnorm(n = nrow(df))
wards@data <- left_join(wards@data, df)

现在(终于回答我的问题了)我想计算平均值 每个人口普查区域中的值,作为每个人口普查区域内的病房的聚合 人口普查区。我认为这就是我计算每次人口普查平均值的方式 道:

ag <- aggregate(x = wards["value"], by = census_tracts_in_wards, FUN = mean)

factor 有没有办法做到这一点?我想要ag 空间 数据框包括factor 列和平均value 列 每个人口普查区。基本上相当于:

result <- df %>% 
  group_by(AREA_ID, factor) %>% 
  summarize(value = mean(value))

但是,由CTUIDcensus_tracts_in_wards 分组,而不是 AREA_IDwards.

正如 Pierre Lafortune 所建议的,公式语法在这里看起来很自然。但是,这些都不起作用:

ag2 <- aggregate(x = wards["value"] ~ wards["factor"], 
  by = census_tracts_in_wards, FUN = mean)
ag3 <- aggregate(x = wards["value" ~ "factor"], 
  by = census_tracts_in_wards, FUN = mean)
ag4 <- aggregate(x = wards["value ~ factor"], 
  by = census_tracts_in_wards, FUN = mean)

也许分组属于 FUN 调用?

【问题讨论】:

  • 查看?aggregate 的公式符号。您可以包含多个要分组的列。
  • 是的,这似乎是自然的语法。我认为像 wards[value ~ factor] 这样的东西会起作用,但事实并非如此。我想我不明白空间对象是如何解释的~。
  • by wards@data &lt;- left_join(wards@data, df) 您创建了一个无效的 wards 对象,其中包含 1110 个面要素和 2220 个属性表条目。如果您只想使用表格,请将wards 转换为带有as.data.frame 的表格。如果你想使用空间聚合,请阅读sp::aggregate 的文档。 aggregate.formulabase 中,对Spatial 对象一无所知。

标签: r gis dplyr sp


【解决方案1】:

在 Edzer Pebesma 的提示下,仔细阅读 sp::aggregate 文档表明 FUN 应用于 x 的每个属性。因此,与其创建一个包含因子列的长表,不如创建两个单独的列(每个因子一个列)似乎可行。

wards2 <- readOGR(dsn = "wards", layer = "VOTING_SUBDIVISION_2010_WGS84") %>%
  spTransform(proj4string(census_tracts))
wards2@data <- dplyr::select(wards2@data, AREA_ID) # Drop the other attributes
df2 <- tidyr::spread(df, factor, value)
wards2@data <- left_join(wards2@data, df2)
ag5 <- aggregate(x = wards2, by = census_tracts_in_wards, FUN = mean)
ag5@data <- dplyr::select(ag5@data, -(AREA_ID)) # The mean of AREA_ID is meaningless 
summary(ag5)
## Object of class SpatialPolygonsDataFrame
## Coordinates:
##         min       max
## x -79.73389 -79.08603
## y  43.56243  43.89091
## Is projected: FALSE 
## proj4string :
## [+init=epsg:4326 +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84
## +towgs84=0,0,0]
## Data attributes:
##        a                  b            
##  Min.   :-1.28815   Min.   :-1.835409  
##  1st Qu.:-0.24883   1st Qu.:-0.289510  
##  Median : 0.01048   Median : 0.008777  
##  Mean   : 0.02666   Mean   :-0.011018  
##  3rd Qu.: 0.25450   3rd Qu.: 0.265358  
##  Max.   : 1.92769   Max.   : 1.399876

【讨论】:

  • 这很好奇。任何有用的错误信息?我只是将其用作将原始问题中的 df 对象从长表重组为宽表的便捷方法。在 sp::aggregate 中为每个因子使用一列的解决方案并不特别需要 tidyr。
  • 我明白了;您的第二个脚本假设您将其与第一个脚本混合;它现在对我有用。在sp::aggregate 中设置areaWeighted=TRUE 似乎会产生微小但显着的差异。
  • 感谢您跟进此事并注意到areaWeighted=TRUE 的影响。这个论点对于产生我的问题的实际分析很重要。
猜你喜欢
  • 2021-10-29
  • 1970-01-01
  • 1970-01-01
  • 2020-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-02
相关资源
最近更新 更多