Jim Lemon
2015-Jul-27 10:50 UTC
[R] Varying name of output tables from looped process of list of spdf objects
Hi Cecilia, I _think_ that the error is occurring in the call to paste0. You may be able to get what you want like this: paste0("distances_",deparse(substitute(fnp)),".txt") Jim On Mon, Jul 27, 2015 at 5:06 AM, Larrosa, Cecilia <cecilia.larrosa10 at imperial.ac.uk> wrote:> Hi, > > This is a repost from here (http://r.789695.n4.nabble.com/Writing-output-of-a-looped-process-with-pdfs-tt4710348.html), due to the post not being complete originally. I am running R studio on OS X Yosemite 10.10.4 (Mac). I appreciate you help very much! > > The objective: I have 100 shapefiles that need to undergo the same process. > > The process: I use gDistance{rgdal} to calculate the distance between all features (polygons) within each layer, and output a txt file. > > The problem: I need the name of the output txt file to contain the name of the shapefile, but the shapefiles are read into R as SpatialPolygonsDataFrames (spdf) and I cannot find a way to use the name of the spdf objects as character in order to make it vary with each iteration. > > My questions to you: Do you know a way to solve the problem or an alternative way to fulfil the objective? I have come to determine the problem after searching about the error message, have I interpreted correctly? > > > Here is a minimal dataset for replicability: > >> dput(a_1) > new("SpatialPolygonsDataFrame" > , data = structure(list(ID = 1:3, GRIDCODE = c(1L, 1L, 1L), Shape_Leng = c(3349.48347556, > 1618.93904903, 893.268790786), Shape_Area = c(309430.38861, 90015.8325676, > 47507.0325775), Count = c(1L, 1L, 1L)), .Names = c("ID", "GRIDCODE", > "Shape_Leng", "Shape_Area", "Count"), row.names = 0:2, class = "data.frame") > , polygons = list(<S4 object of class structure("Polygons", package = "sp")>, > <S4 object of class structure("Polygons", package = "sp")>, > <S4 object of class structure("Polygons", package = "sp")>) > , plotOrder = 1:3 > , bbox = structure(c(476685.625393809, 311791.86152084, 508519.585393809, > 312935.41622084), .Dim = c(2L, 2L), .Dimnames = list(c("x", "y" > ), c("min", "max"))) > , proj4string = new("CRS" > , projargs = "+proj=aea +lat_1=-5 +lat_2=-42 +lat_0=-32 +lon_0=-60 +x_0=0 +y_0=0 +ellps=aust_SA +units=m +no_defs" > ) > ) >> dput(a_10) > new("SpatialPolygonsDataFrame" > , data = structure(list(ID = 1:5, GRIDCODE = c(1L, 1L, 1L, 1L, 1L), Shape_Leng = c(1691.7247095, > 2305.45647624, 1022.64650591, 1172.27848042, 94.2722341164), > Shape_Area = c(6.47354525991, 92111.8528756, 65.7173995386, > 19042.7776647, 415.253663691), Count = c(1L, 1L, 1L, 1L, > 1L)), .Names = c("ID", "GRIDCODE", "Shape_Leng", "Shape_Area", > "Count"), row.names = 0:4, class = "data.frame") > , polygons = list(<S4 object of class structure("Polygons", package = "sp")>, > <S4 object of class structure("Polygons", package = "sp")>, > <S4 object of class structure("Polygons", package = "sp")>, > <S4 object of class structure("Polygons", package = "sp")>, > <S4 object of class structure("Polygons", package = "sp")>) > , plotOrder = c(2L, 4L, 5L, 3L, 1L) > , bbox = structure(c(825796.904693809, 815666.86152084, 831270.106493809, > 816562.46752084), .Dim = c(2L, 2L), .Dimnames = list(c("x", "y" > ), c("min", "max"))) > , proj4string = new("CRS" > , projargs = "+proj=aea +lat_1=-5 +lat_2=-42 +lat_0=-32 +lon_0=-60 +x_0=0 +y_0=0 +ellps=aust_SA +units=m +no_defs" > ) > ) > > > Here is the code that I have been using: > > ###Load packages > library(rgdal) > library(gdistance) > > ###Read forest shape files > setwd("/Users/sisolarrosa/Documents/PhD/R_work/AF/IIC/R_Quest/") > shps<- dir(getwd(), "*.shp") > shps <- gsub('.{4}$', '', shps) > for (shp in shps) assign(shp, readOGR(".",layer=shp)) > > ###Create list of spdf objects > fnps<- mget(ls(pattern= "a_")) > > ###For each spatial layer (object in the list), calculate distance between all polygons within layer > for (fnp in fnps) > { > distance.matrix<- gDistance(fnp, spgeom2= NULL, byid=T); > row.names(distance.matrix) <- paste(1:nrow(distance.matrix), sep="?); # did this because gDistance changed the IDs of the features from [1 to ...] to [0 to ...], not sure why > colnames(distance.matrix)<- paste(1:ncol(distance.matrix), sep="?); # same as above > dists.melt <- melt(distance.matrix)[melt(upper.tri(distance.matrix))$value,]; #use only lower triangle of the distances matrix > outfile <- file.path("/Users/sisolarrosa/Documents/PhD/R_work/AF/IIC/conefor_inputs/", paste0("distances_", fnp, ".txt")); > write.table(dists.melt, outfile,row.names=FALSE, col.names=FALSE) > } > > And this is the error message: > > Error in as.character.default(<S4 object of class "SpatialPolygonsDataFrame">) : > no method for coercing this S4 class to a vector > > Thank you very much!! > Cecilia > > > [[alternative HTML version deleted]] > > ______________________________________________ > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code.
Anthoni, Peter (IMK)
2015-Jul-27 13:14 UTC
[R] Varying name of output tables from looped process of list of spdf objects
Hi Cecilia, Alternative solution #... afiles <- ls(pattern= "a_") for (ifile in 1:length(afiles)) { fnp = mget(afiles[ifile]) #... do something with fnp outfile <- file.path("/Users/sisolarrosa/Documents/PhD/R_work/AF/IIC/conefor_inputs/", paste0("distances_", afiles[ifile], ".txt")); #... } cheers Peter> On 27 Jul 2015, at 12:50, Jim Lemon <drjimlemon at gmail.com> wrote: > > Hi Cecilia, > I _think_ that the error is occurring in the call to paste0. You may > be able to get what you want like this: > > paste0("distances_",deparse(substitute(fnp)),".txt") > > Jim > > > On Mon, Jul 27, 2015 at 5:06 AM, Larrosa, Cecilia > <cecilia.larrosa10 at imperial.ac.uk> wrote: >> Hi, >> >> This is a repost from here (http://r.789695.n4.nabble.com/Writing-output-of-a-looped-process-with-pdfs-tt4710348.html), due to the post not being complete originally. I am running R studio on OS X Yosemite 10.10.4 (Mac). I appreciate you help very much! >> >> The objective: I have 100 shapefiles that need to undergo the same process. >> >> The process: I use gDistance{rgdal} to calculate the distance between all features (polygons) within each layer, and output a txt file. >> >> The problem: I need the name of the output txt file to contain the name of the shapefile, but the shapefiles are read into R as SpatialPolygonsDataFrames (spdf) and I cannot find a way to use the name of the spdf objects as character in order to make it vary with each iteration. >> >> My questions to you: Do you know a way to solve the problem or an alternative way to fulfil the objective? I have come to determine the problem after searching about the error message, have I interpreted correctly? >> >> >> Here is a minimal dataset for replicability: >> >>> dput(a_1) >> new("SpatialPolygonsDataFrame" >> , data = structure(list(ID = 1:3, GRIDCODE = c(1L, 1L, 1L), Shape_Leng = c(3349.48347556, >> 1618.93904903, 893.268790786), Shape_Area = c(309430.38861, 90015.8325676, >> 47507.0325775), Count = c(1L, 1L, 1L)), .Names = c("ID", "GRIDCODE", >> "Shape_Leng", "Shape_Area", "Count"), row.names = 0:2, class = "data.frame") >> , polygons = list(<S4 object of class structure("Polygons", package = "sp")>, >> <S4 object of class structure("Polygons", package = "sp")>, >> <S4 object of class structure("Polygons", package = "sp")>) >> , plotOrder = 1:3 >> , bbox = structure(c(476685.625393809, 311791.86152084, 508519.585393809, >> 312935.41622084), .Dim = c(2L, 2L), .Dimnames = list(c("x", "y" >> ), c("min", "max"))) >> , proj4string = new("CRS" >> , projargs = "+proj=aea +lat_1=-5 +lat_2=-42 +lat_0=-32 +lon_0=-60 +x_0=0 +y_0=0 +ellps=aust_SA +units=m +no_defs" >> ) >> ) >>> dput(a_10) >> new("SpatialPolygonsDataFrame" >> , data = structure(list(ID = 1:5, GRIDCODE = c(1L, 1L, 1L, 1L, 1L), Shape_Leng = c(1691.7247095, >> 2305.45647624, 1022.64650591, 1172.27848042, 94.2722341164), >> Shape_Area = c(6.47354525991, 92111.8528756, 65.7173995386, >> 19042.7776647, 415.253663691), Count = c(1L, 1L, 1L, 1L, >> 1L)), .Names = c("ID", "GRIDCODE", "Shape_Leng", "Shape_Area", >> "Count"), row.names = 0:4, class = "data.frame") >> , polygons = list(<S4 object of class structure("Polygons", package = "sp")>, >> <S4 object of class structure("Polygons", package = "sp")>, >> <S4 object of class structure("Polygons", package = "sp")>, >> <S4 object of class structure("Polygons", package = "sp")>, >> <S4 object of class structure("Polygons", package = "sp")>) >> , plotOrder = c(2L, 4L, 5L, 3L, 1L) >> , bbox = structure(c(825796.904693809, 815666.86152084, 831270.106493809, >> 816562.46752084), .Dim = c(2L, 2L), .Dimnames = list(c("x", "y" >> ), c("min", "max"))) >> , proj4string = new("CRS" >> , projargs = "+proj=aea +lat_1=-5 +lat_2=-42 +lat_0=-32 +lon_0=-60 +x_0=0 +y_0=0 +ellps=aust_SA +units=m +no_defs" >> ) >> ) >> >> >> Here is the code that I have been using: >> >> ###Load packages >> library(rgdal) >> library(gdistance) >> >> ###Read forest shape files >> setwd("/Users/sisolarrosa/Documents/PhD/R_work/AF/IIC/R_Quest/") >> shps<- dir(getwd(), "*.shp") >> shps <- gsub('.{4}$', '', shps) >> for (shp in shps) assign(shp, readOGR(".",layer=shp)) >> >> ###Create list of spdf objects >> fnps<- mget(ls(pattern= "a_")) >> >> ###For each spatial layer (object in the list), calculate distance between all polygons within layer >> for (fnp in fnps) >> { >> distance.matrix<- gDistance(fnp, spgeom2= NULL, byid=T); >> row.names(distance.matrix) <- paste(1:nrow(distance.matrix), sep="?); # did this because gDistance changed the IDs of the features from [1 to ...] to [0 to ...], not sure why >> colnames(distance.matrix)<- paste(1:ncol(distance.matrix), sep="?); # same as above >> dists.melt <- melt(distance.matrix)[melt(upper.tri(distance.matrix))$value,]; #use only lower triangle of the distances matrix >> outfile <- file.path("/Users/sisolarrosa/Documents/PhD/R_work/AF/IIC/conefor_inputs/", paste0("distances_", fnp, ".txt")); >> write.table(dists.melt, outfile,row.names=FALSE, col.names=FALSE) >> } >> >> And this is the error message: >> >> Error in as.character.default(<S4 object of class "SpatialPolygonsDataFrame">) : >> no method for coercing this S4 class to a vector >> >> Thank you very much!! >> Cecilia >> >> >> [[alternative HTML version deleted]] >> >> ______________________________________________ >> R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see >> https://stat.ethz.ch/mailman/listinfo/r-help >> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html >> and provide commented, minimal, self-contained, reproducible code. > > ______________________________________________ > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code.
SisoL
2015-Jul-27 16:26 UTC
[R] Varying name of output tables from looped process of list of spdf objects
Hi Jim, I've tried your suggestion but it just prints "fnp" and not the iterating names (a_1, a_10, etc). Any other suggestions? Thank you very much Siso -- View this message in context: http://r.789695.n4.nabble.com/Varying-name-of-output-tables-from-looped-process-of-list-of-spdf-objects-tp4710369p4710406.html Sent from the R help mailing list archive at Nabble.com.
SisoL
2015-Jul-27 16:33 UTC
[R] Varying name of output tables from looped process of list of spdf objects
Hi Peter, Thank you for your reply. The method for looping seems to work, but gDistance will not recognise the input. I am puzzled because when I print(fnp), and print (a_10) they look exactly the same, but when I try to run gDistance{rgeos} with a_10 it works, but with fnp it throws an error. Please see below. Any other suggestions?>afiles <- ls(pattern= "a_") #OK >print(afiles)[1] "a_1" "a_10">fnp<- mget(afiles[ifile]) #OK> print(fnp)$a_10 class : SpatialPolygonsDataFrame features : 5 extent : 825796.9, 831270.1, 815666.9, 816562.5 (xmin, xmax, ymin, ymax) coord. ref. : +proj=aea +lat_1=-5 +lat_2=-42 +lat_0=-32 +lon_0=-60 +x_0=0 +y_0=0 +ellps=aust_SA +units=m +no_defs variables : 5 names : ID, GRIDCODE, Shape_Leng, Shape_Area, Count min values : 1, 1, 94.2722341164, 6.47354525991, 1 max values : 5, 1, 2305.45647624, 92111.8528756, 1> print(a_10)class : SpatialPolygonsDataFrame features : 5 extent : 825796.9, 831270.1, 815666.9, 816562.5 (xmin, xmax, ymin, ymax) coord. ref. : +proj=aea +lat_1=-5 +lat_2=-42 +lat_0=-32 +lon_0=-60 +x_0=0 +y_0=0 +ellps=aust_SA +units=m +no_defs variables : 5 names : ID, GRIDCODE, Shape_Leng, Shape_Area, Count min values : 1, 1, 94.2722341164, 6.47354525991, 1 max values : 5, 1, 2305.45647624, 92111.8528756, 1>distance.matrix<- gDistance(fnp, spgeom2= NULL, byid=T)Error in (function (classes, fdef, mtable) : unable to find an inherited method for function ?is.projected? for signature ?"list"? -- View this message in context: http://r.789695.n4.nabble.com/Varying-name-of-output-tables-from-looped-process-of-list-of-spdf-objects-tp4710369p4710408.html Sent from the R help mailing list archive at Nabble.com.