Search code examples
rloopsfor-looppoints

Proper points() use in multiples maps with for loop


I would like to make several maps (one for each species of my dataset), but somehow I am not able to achieve what I am looking for.

I want to plot every species record in its map, but I just create maps with a single dot in it for each one... I cannot understand what is wrong with my script. Could you help me? Thank you!

elevation <- getData("alt", country = "ES", mask=F)
slope <- terrain(elevation, opt = "slope",neighbors=4) 
aspect <- terrain(elevation, opt = "aspect",neighbors=4)
hill <- hillShade(slope, aspect, 40, 270)
newextent<-extent(-7.99, -2.87, 39.9, 41.5)
land.pal <- colorRampPalette(c("#336600", "#F3CA89", "#D9A627", 
                               "#A49019", "#9F7B0D", "#996600", "#B27676", "#C2B0B0", "#E5E5E5", 
                               "#FFFFFF"), space="Lab") (1000)


for (i in seq_along(data$Species)) {
  pdf(file=paste0("map ", data$Species[[i]],".pdf"), onefile=F)
  plot(disaggregate(crop(elevation,newextent), 1, method="bilinear"), col = land.pal, legend=F)  
  points(data$Lat[[i]],data$Long[[i]], col="black") ##The error must be here, but I cannot fix it
  dev.off()
}

Thank you in advance

Data:

Lat Long    Species
-6.99   40.49   Sp1
-5.05   40.60   Sp1
-3.30   40.02   Sp1
-7.51   40.86   Sp1
-3.18   40.24   Sp1
-3.83   40.08   Sp1
-7.28   40.91   Sp1
-7.74   40.53   Sp1
-7.72   40.69   Sp1
-4.36   40.06   Sp1
-5.90   40.51   Sp2
-5.56   40.07   Sp2
-3.52   40.19   Sp3
-6.29   40.93   Sp3
-6.77   40.12   Sp3
-7.11   40.77   Sp4
-5.81   40.88   Sp4
-5.27   40.68   Sp4
-6.31   40.34   Sp4
-6.13   40.32   Sp4
-6.73   40.99   Sp4
-5.32   40.71   Sp4
-6.17   40.97   Sp4
-4.77   40.92   Sp4
-6.45   40.58   Sp5
-5.54   40.39   Sp5
-6.56   40.66   Sp5
-5.27   40.37   Sp5

Solution

  • Currently, you are iterating through every single value of your Species column and not Species as a whole group and you pass one point of Lat and Long, so one row is being passed in for loop.

    Hence, consider by to slice your data frame by the Species factor, iteratively passing every sliced data frame into a function. Not shown below but by can return a named list of objects equal to the groupings of factor(s) here being Species:

    by(data, data$Species, FUN = function(df) {
      pdf(file=paste0("map ", df$Species[[1]],".pdf"), onefile=FALSE)
      plot(disaggregate(crop(elevation,newextent), 1, method="bilinear"), col = land.pal, legend=FALSE)  
      points(df$Lat, df$Long, col="black")
      dev.off()
    })