Loop through each row in a data frame, extract values from raster and write csv files

37,092

Solution 1

A very traditional method works with a for-loop

d1 <-c("Name1", "Name2","Name3", "Name4")
d2 <- c(11.11,150.1,-50.2,-100.3)
d3 <-c(47.87, -40.4, -3.5, 49.8)
data.df <-data.frame(d1,d2,d3)

for(i in 1:nrow(data.df)) 
{
  location <- data.frame(data.df[i,2],data.df[,3])
  ex <- extract(s, location)
  fn1<-paste0(data.df[i,1],".csv")
  write.csv(ex, fn1)
}

Four files are generated containing information like:

"","layer.1","layer.2","layer.3","layer.4","layer.5"
"1",0.471816286211833,0.115963410818949,0.399704266572371,0.464667820138857,0.820669727399945
"2",0.616754011251032,0.354018000885844,0.602565947687253,0.86519843316637,0.660861984360963
"3",0.0691961287520826,0.128835600335151,0.199198298621923,0.968016018159688,0.597145217470825

I hope that's the result you are looking for. There might be some more advanced and performing method (based on apply-family???) and as a R beginner am interested in as well.

Solution 2

With apply :

library(raster)
s <- stack(replicate(5, {raster(matrix(runif(2160*4320), 2160), 
                                xmn=-180, xmx=180, ymn=-90, ymx=90)}))

d1 <-c("Name1", "Name2","Name3", "Name4")
d2 <- c(11.11,150.1,-50.2,-100.3)
d3 <-c(47.87, -40.4, -3.5, 49.8)
data.df <- data.frame("Name" = d1, "Lon" = d2, "Lat" = d3)

apply(X = data.df, 1, function(x, s) {
        location <- as.numeric(c(x[2], x[3]))
        ex <- extract(s, location)
        write.csv(ex, paste0(x[1], ".csv"))
}, s = s)

Note that, if this is to used inside a function, you have to pass the s object as an additional argument to your function.

Share:
37,092

Related videos on Youtube

Geo-sp
Author by

Geo-sp

Geo-spatial analysis

Updated on January 13, 2020

Comments

  • Geo-sp
    Geo-sp over 4 years

    I have a data frame with a Name, longitude and latitude columns. I want a function that goes trough each row, extract the values from a raster stack and write csv files based on the Name column.

    Name    Lon     Lat
    Name1   11.11   47.87
    Name2   150.1   -40.4
    Name3   -50.2   -3.5
    Name4   -100.3  49.8
    
    library(raster)
    s <- stack(replicate(5, {raster(matrix(runif(2160*4320), 2160), 
             xmn=-180, xmx=180, ymn=-90, ymx=90)}))
    
    I can do that one by one:
    
    location <- data.frame(11.11, 47.87)
    ex <- extract(s, location)
    write.csv(ex, "Name1.csv")
    
  • Robert Hijmans
    Robert Hijmans over 8 years
    It would be more efficient do call extract only once by doing ex <- extract(s, data.df[,2:3]) before the loop.