Reputation: 6116
I'm having a little trouble programming stuff in R that I would normally do in a for loop in another language...
I am now trying to make a plot using spplot from the sp package (it's a chloropleth map), but I want to do it for a bunch of variables. In a for loop, I would program it like this:
for (TRAIT in c("height","bmi","whr","body_fat","income")){
pdf("plot_of_TRAIT.pdf")
spplot(MyData, "TRAIT", col.regions = my.palette, cuts = 8, lwd = 0.5)
dev.off()
}
where each instance of TRAIT should be replaced by the variables I give to the for loop (so in the filename of the pdf, and as an argument in the spplot command). Now, obviously this code does not work, but how would one go about doing this in R?
UPDATE:
I got the code to create different pdf files, but the spplot command still will not work. It creates empty pdf files:
for (TRAIT in c("height","bmi","whr","body_fat","income")){
outfile <- paste0("plot_of_", TRAIT, ".pdf")
pdf(outfile)
spplot(MyData, TRAIT, col.regions = my.palette, cuts = 8, lwd = 0.5)
dev.off()
}
If I run the exact same code outside of the for loop like this:
pdf("plot_of_height.pdf")
spplot(MyData, "height", col.regions = my.palette, cuts = 8, lwd = 0.5)
dev.off()
it works fine and I get the desired plot in the file plot_of_height.pdf.
UPDATE 2: This seems to be an issue with spplot. If I run this:
TRAIT <- "height"
pdf("plot_of_height.pdf")
spplot(MyData, TRAIT, col.regions = my.palette, cuts = 8, lwd = 0.5)
dev.off()
I get the following error:
Error in [.data.frame(obj@data, zcol) : undefined columns selected
Upvotes: 2
Views: 815
Reputation: 1688
Without looking at your data, I cannot say why you have the undefined column error. Replicating your 'UPDATE 2' code with the meuse dataset does not throw the same error for me:
library(sp)
demo(meuse, ask = FALSE, echo = FALSE)
TRAIT <- "copper"
my.palette <- c("black", "red", "green", "blue")
spplot(meuse, TRAIT, col.regions = my.palette, cuts = 8, lwd = 0.5)
As for the first case of your question: spplot
(much like ggplot
) won't output anything to the device from within a loop unless explicitly printed. Basically you are opening a pdf file, creating the plot but not saving it to the pdf file, then
The following code should work for you:
for (TRAIT in c("height","bmi","whr","body_fat","income")){
outfile <- paste0("plot_of_", TRAIT, ".pdf")
pdf(outfile)
print(spplot(MyData, TRAIT, col.regions = my.palette, cuts = 8, lwd = 0.5))
dev.off()
}
I tested it using the Meuse dataset and it worked fine there:
library(sp)
demo(meuse, ask = FALSE, echo = FALSE)
my.palette <- c("black", "red", "green", "blue")
for(TRAIT in c("cadmium", "copper", "lead", "zinc")){
outfile <- paste0("plot_of_", TRAIT, ".pdf")
pdf(outfile)
print(spplot(meuse, TRAIT, col.regions = my.palette, cuts = 8, lwd = 0.5))
dev.off()
}
Giving me 4 distinct pdfs, each containing the spatial plot of the corresponding variable.
Upvotes: 1
Reputation: 33802
You need to construct the output file name using the variable.
For example:
outfile <- paste0("plot_of_", TRAIT, ".pdf")
pdf(outfile)
For spplot
you probably need to use TRAIT
(no quotes).
EDIT:
Since spplot(zcol = ...
can be a column number, I wonder if this might work?
traits <- c("height","bmi","whr","body_fat","income")
for(i in 1:length(traits)) {
pdf(paste0("plot_of_", traits[i], ".pdf")
spplot(MyData, i, col.regions = my.palette, cuts = 8, lwd = 0.5)
dev.off()
}
Upvotes: 2