# How to use R to extract data from WorldClim?

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'm a newbie at GIS in R, so I seek a basic code chunk along with the required libraries for this output.

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.

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]])

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
• That was really helpful! – Ash Feb 8 '17 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 '17 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 '17 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 '17 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 '17 at 11:16

## protected by Community♦Oct 24 '17 at 12:05

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).