1

I have a dataframe consisting of species names, longitude and latitude coordinates. there are 115 different species with 25000 lat/long coordinates. I need to make individual maps that show observations for each specific species.

first, I created a function that would generate the kind of map that I want, called platmaps. when I call the function for my full dataset (platmaps(df1)), it creates a map displaying all lat long observations.

Then I constructed a for loop which was supposed to subset my df by species name, and insert that subsetted dataframe into my platmaps function. It runs for a couple of minutes and then nothing happens.

so I then I split the dataframe by species name, and created a list of dataframes(out1), and used lapply(out1, platmaps) but it only returned a list of the names of my dfs.

Then I tried a variation of an example that I saw here, but it also did not work.

function

platmaps<-function(df1){
wm <- wm <- borders("world", colour="gray50", fill="gray50")
ggplot()+ 
coord_fixed()+
wm +
geom_point(data =df1 , aes(x = decimalLongitude, y = decimalLatitude),
           colour = "pink", size = 0.5)

subset

for(i in 1:nrow(PP)){
query<-paste(PP$species[i])
p<-subset(df1, df1$species== query))
platmaps(p)
}

list

for (i in 1:length(out1)){
pp<-out1[[i]] 
platmaps(pp)

}

applied example

p =  
wm <- wm <- borders("world", colour="gray50", fill="gray50")
ggplot()+ 
coord_fixed()+
wm +
geom_point(data =df1 , aes(x = decimalLongitude, y = decimalLatitude),
         colour = "pink", size = 0.5)
plots = df1 %>%
group_by(species) %>%
do(plots = p %+% . + facet_wrap(~species))

the error for the applied example is:

Error: Cannot add ggproto objects together. Did you forget to add this object to a ggplot object?

As I'm new to R (and coding), I assume I'm getting the syntax wrong, or am not applying my function correctly to/within either of my loops, or I fundamentally misunderstand the way looping works.

data frame sample

species                        decimalLongitude     decimalLatitude
  Platanthera lacera        -71.90000        42.80000
  Platanthera lacera        -90.54861        40.12083
  Platanthera lacera        -71.00889        42.15500
  Platanthera lacera        -93.20833        45.20028
  Platanthera lacera        -72.45833        41.91666
 Platanthera bifolia          5.19800        59.64310
 Platanthera sparsiflora       -117.67472        34.36278

fixed platmaps function

ggplot(data=df1 %>% filter(species == s))+ 
  coord_fixed()+
  borders("world", colour="gray50", fill="gray50")+
  geom_point(aes(x = decimalLongitude, y = decimalLatitude),
             colour = "pink", size = 0.5)+
labs(title=as.character(s))
dplyd
  • 25
  • 5
  • Hi dplyd welcome to SO, if you could provide us with a reproducible example (some data if possible [see here for an explanation on making a reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example)) I am sure we could help you solve your problem. – Croote Oct 17 '19 at 23:38
  • Hi Croote, sorry about that! I've added a hyperlink and a visual of a sample of my larger df. – dplyd Oct 18 '19 at 00:14

2 Answers2

0

Because you didn't provide a test data set, let me give you a general idea how to make multiple plots you can inspect later. The code below will plot a parameter for a number of countries and save plot pdfs to a given path. You can replace the code behind the pl variable in the loop with your function.

library(ggplot2)
library(dplyr)

df <- data.frame(country = c(rep('USA',20), rep('Canada',20), rep('Mexico',20)),
                 wave = c(1:20, 1:20, 1:20),
                 par = c(1:20 + 5*runif(20), 21:40 + 10*runif(20), 1:20 + 15*runif(20)))

countries <- unique(df$country)

plot_list <- list()
i <- 1

for (c in countries){
  pl <- ggplot(data = df %>% filter(country == c)) +
    geom_point(aes(wave, par), size = 3, color = 'red') +
    labs(title = as.character(c), x = 'wave', y = 'value') +
    theme_bw(base_size = 16)

  plot_list[[i]] <- pl
  i <- i + 1
}

pdf('path/to/pdf')
pdf.options(width = 9, height = 7)
for (i in 1:length(plot_list)){
  print(plot_list[[i]])
}
dev.off()

After the plots are obtained (the plot_list variable), we turn on the pdf terminal and print them. In the end, we turn off the pdf terminal.

slava-kohut
  • 4,203
  • 1
  • 7
  • 24
  • Thank you so much! that worked! I also had to change my platmaps function a bit to get an intelligible plot: – dplyd Oct 18 '19 at 16:25
  • ggplot(data=df1 %>% filter(species == s))+ coord_fixed()+ borders("world", colour="gray50", fill="gray50")+ geom_point(aes(x = decimalLongitude, y = decimalLatitude), colour = "blue", size = 0.5) – dplyd Oct 18 '19 at 16:26
0

there is a neat way to apply any function to a list of items. I have outlined a way to do this with the data you added. I cannot get platmaps to work so I have just made a scatter plot.

The method is to split your data frame into individual subsets using split() and then apply the plotting function to the resulting list using lapply(). Since lapply() returns a list, this can be passed directly to a function such as ggpubr::ggarrange() for visualizing.

library(ggplot2)
plot_function <- function(x){

  p <- ggplot(x, aes(x = decimalLongitude, y = decimalLatitude)) + geom_point()

  p

}

plot_list <- 
df %>% 
  split(.$species) %>% # Separate df into subset dfs based on species column
  lapply(., plot_function) # map plot_function to list

# Display on a grid (many ways to do this - I just find this package simple)
ggpubr::ggarrange(plotlist = plot_list)
Croote
  • 1,382
  • 1
  • 7
  • 15