11

I have a data set with 1000 different latitudes-longitudes. I wish to extract average annual temperature and annual precipitation for each of these coordinates. These data can easily be obtained from WorldClim and processed using DIVA-GIS.

Is there anyway to do this on R?

I want my final output to be a dataframe with the annual temperature and precipitation for each coordinate. I am new at GIS in R, so I seek a basic code chunk along with the required libraries for this output.

1 Answer 1

21

You can use raster package to download WorldClim data, see ?getdata to know about resolution, variables and coordinates.

As example:

library(raster)
library(sp)

r <- getData("worldclim",var="bio",res=10)

Bio 1 and Bio12 are mean anual temperature and anual precipitation:

r <- r[[c(1,12)]]
names(r) <- c("Temp","Prec")

I create random points as example, in your case use coordinates to create a SpatialPoint object.

points <- spsample(as(r@extent, 'SpatialPolygons'),n=100, type="random")    

Finally, use extract. With cbind.data.frame and coordinates you will get the desire data.frame.

values <- extract(r,points)

df <- cbind.data.frame(coordinates(points),values)

I used random points, so I got a lot of NA. It is to be expected.

head(df)
           x          y Temp Prec
1  112.95985  52.092650  -37  388
2  163.54612  85.281643   NA   NA
3   30.95257   5.932434  270  950
4   64.66979  40.912583  150  150
5 -169.40479 -58.889104   NA   NA
6   51.46045  54.813600   36  549

plot(r[[1]])
plot(points,add=T)

enter image description here

Don't forget that WorldClim data has a scale factor of 10, so Temp = -37 is -3.7 ºC.


With coordinates example:

library(raster)
library(sp)

r <- getData("worldclim",var="bio",res=10)

r <- r[[c(1,12)]]
names(r) <- c("Temp","Prec")

lats <- c(9.093028 , 9.396111, 9.161417)
lons <- c(-11.7235, -11.72975, -11.709417) 

coords <- data.frame(x=lons,y=lats)

points <- SpatialPoints(coords, proj4string = r@crs)

values <- extract(r,points)

df <- cbind.data.frame(coordinates(points),values)

df
          x        y Temp Prec
1 -11.72350 9.093028  257 2752
2 -11.72975 9.396111  257 2377
3 -11.70942 9.161417  257 2752
7
  • That was really helpful!
    – Ash
    Feb 8, 2017 at 17:28
  • So, I have points which is a dataframe of lats and longs of my data set. Then I run exactly the way you did. However, when I run values I get an error : not compatible with requested type. I also noticed that your points just marks the extent of the sample, but does not produce a vector with lat-long coordinates
    – Ash
    Feb 8, 2017 at 17:54
  • Yes, degree decimals. Because CRS of WorldClim is WGS 84 lat/lon (EPSG 4326). You can import coordinates in a different CRS and convert it with spTransform. If you have coordinates in DDMMSS, transform it into DD.MMM. Second, you wrote about different coordinates, so I interpret it as points, you can use polygons instead with same schema. If you have a layer with this information, use shapefile to load it.
    – aldo_tapia
    Feb 8, 2017 at 18:00
  • I don't get your second point. Perhaps, I did not explain clearly. I have marked the error here : eval.in/733232
    – Ash
    Feb 8, 2017 at 18:09
  • Ah, ok. spsample requires an spatial object to set sample boundaries. Inputs are grids, polygons or lines. What I did was to use WorlClim boundary box to set sample extent. I did it to make a reproducible example in my answer. In your case, you don't need to use spsample, you have already coordinates to sample.
    – aldo_tapia
    Feb 9, 2017 at 11:16

Not the answer you're looking for? Browse other questions tagged or ask your own question.