2016-09-15 60 views
2

我有一个位置数据框,我一直想要将它们与地图上的分类变量(气候区域)进行匹配。这里是一个小摘录:R从网格数据中提取点的提取类别

df <- data.frame(lat = c(29.30050, 47.67309, 53.30710, -27.60303, 41.31858, 40.50738, 
         50.67013,60.23163, 42.54555), 
       long = c(47.806320, -122.315312, -6.281798, 151.951778, -72.849961, 
          -74.382711, 4.348718, 19.710874, -71.038764)) 

我学会了从哪里该excellent article获取数据。我想要做的是为我的数据框中的每个点集提取分类变量。这可能听起来微不足道,但我是映射的新手,并且找不到任何帮助文章。问题可能是我使用了错误的术语!

映射数据集在本教程中非常简单,但网格匹配不在我身边。分类地图数据可以使用.txt,.kmz或GIS格式here,因此我不仅限于一种方法。

我已经尝试了最近匹配的每个拉特和长,但它没有区分网格的哪一侧可供选择。我通过关于牧师,rworldmap,rgdal和堆栈溢出的所有搜索组合的文档来挖掘。

+0

你在寻找一个空间覆盖?另外,是否可以通过''rworldmap''获取相同的数据? –

+1

虽然我发布的教程链接来自rworldmap编写者,但我没有在rworldmap文档中看到关于内部气候区域映射的任何内容。我能够很容易地将两者映射在一起,但不能提取类别。下面的alistaire的答案是诀窍。 –

回答

3

如果我们从网站上下载数据并将其作为koeppen(例如,

download.file('http://koeppen-geiger.vu-wien.ac.at/data/Koeppen-Geiger-ASCII.zip', 
       'Koeppen-Geiger-ASCII.zip', 
       method = 'curl') 

# use read.table if you like, but read_table cuts a lot of hassle with poor formatting 
koeppen <- readr::read_table('Koeppen-Geiger-ASCII.zip') 

,我们看一下数据,所有的经度和纬度不便与.25.75结束:

koeppen 
## # A tibble: 92,416 × 3 
##  Lat  Lon Cls 
##  <dbl> <dbl> <chr> 
## 1 -89.75 -179.75 EF 
## 2 -89.75 -179.25 EF 
## 3 -89.75 -178.75 EF 
## 4 -89.75 -178.25 EF 
## 5 -89.75 -177.75 EF 
## 6 -89.75 -177.25 EF 
## 7 -89.75 -176.75 EF 
## 8 -89.75 -176.25 EF 
## 9 -89.75 -175.75 EF 
## 10 -89.75 -175.25 EF 
## # ... with 92,406 more rows 

因此,合并两个表,我们需要圆df的纬度和经度为.25.75,例如通过

df[] <- lapply(df, function(x){ifelse(x %% 1 > .5, 0.75, 0.25) + floor(x)}) 

得到剩余由一个划分,即非整数部分,如果它是大于.5回报.75,否则返回.25,然后重新添加的整数部分,所以df现在看起来像:现在

df 
##  lat long 
## 1 29.25 47.75 
## 2 47.75 -122.25 
## 3 53.25 -6.25 
## 4 -27.75 151.75 
## 5 41.25 -72.75 
## 6 40.75 -74.25 
## 7 50.75 4.25 
## 8 60.25 19.75 
## 9 42.75 -71.25 

我们可以使用merge(或dplyr加入,如果您愿意)为Cls列添加到df匹配的纬度和经度:

df <- merge(df, koeppen, 
      by.x = c('lat', 'long'), 
      by.y = c('Lat', 'Lon'), 
      all.x = TRUE) 

# or dplyr::left_join(df, koeppen, by = c('lat' = 'Lat', 'long' = 'Lon')) 

df 
##  lat long Cls 
## 1 -27.75 151.75 Cfa 
## 2 29.25 47.75 BWh 
## 3 40.75 -74.25 Cfa 
## 4 41.25 -72.75 Cfa 
## 5 42.75 -71.25 Dfb 
## 6 47.75 -122.25 Csb 
## 7 50.75 4.25 Cfb 
## 8 53.25 -6.25 Cfb 
## 9 60.25 19.75 Dfb 

如果你喜欢语法,这可能也是data.table's non-equi-joins的好例子。

+0

这完全是我所需要的!我只是在使用'round_any(df [,1],0.25,floor)'工作,当然,当我得到你的回应时,我发现我的一个问题是0.25和0.75。我仍在学习如何使用%%修饰符,这有助于我更好地理解它是如何工作的。非常感谢你! –

+1

'%/%'和'%%'给你一个长整数部分的答案:'%/%',称为整数或者整数除法,给你整数部分; '%%'给出余数(也称为模),所以'7%/%3'返回2,'7 %% 3'返回1。 – alistaire