Hello,
I was wondering if anyone could help me with some R- script I got from a client, and I want to integrate it to my Model Builder. I have installed R-ArcGIS bridge and all required packages, and tested the script as standalone tool with hard-coded parameters and it works fine. The problem I have is how to create variables for the input and output parameters.
If you get a chance, will you spend few hour to assist with the attached R script. I tried to use the in_params & out_params for inputs and outputs respectively, but no luck except the path to the folder.
Here is what I need:
Inputs:
Outputs:
Thanks in advance,
Daniel
Solved! Go to Solution.
Thank shaun for the reply. But I think I figure that out. This is how I did it. Even though it is messy, it is working !!
tool_exec <- function(in_params, out_params)
{
# load the required packages
cat(paste0("\n", "Loading packages...", "\n"))
library(arcgisbinding)
arc.check_product()
# read input and output parameters
folder_path=in_params[[1]]# folder path
shp_name=in_params[[2]] # input shapefile name
n=as.integer(in_params[[3]])# write in how many random sites you want selected
m=as.integer(in_params[[4]])#write in how many "contingency" random sites
out_shp=in_params[[5]] # output shapefile name
setwd(folder_path)# shapefile path
extension <- ".dbf"
dbfFile = paste (shp_name,extension,sep="")# concatnate
library(spsurvey)
att <- read.dbf(dbfFile) # write in the name of your
# random point shapefile and add the file
# extension .dbf
att$stratum <- rep("Study", nrow(att))
dsgn <- list("Study"=list(panel=c(Base=n),
seltype='Equal',
over=m))
set.seed(3216530) # Do not need to change. But if you keep it constant
#it will allow you to redo the sample and get the same sites.
sites <- grts(design=dsgn,
DesignID='watershed',
SiteBegin=1, # default so can leave out
type.frame='finite',
src.frame='shapefile', # default so can leave out
in.shape=shp_name,
att.frame=att,
stratum='stratum',
mdcaty='MDCATY',
shapefile=TRUE,
out.shape=out_shp, #Name your output shape file
prjfilename=shp_name) #Copy same name as in.shape
#Done! Go and open the new point shapefile in ArcGIS.
cat(paste0("\n", "Done.", "\n"))
}
load_pkgs <- function(pkgs) {
new_pkgs = pkgs[(pkgs %in% installed.packages()[ ,'Package'])]
if (length(new_pkgs) > 0) install.packages(new_pkgs)
invisible(lapply(pkgs, function(x)
suppressMessages(library(x, character.only = TRUE)))
)
}
Daniel,
Have you built the corresponding Geoprocessing tool already? That's the first step -- select the data types and variables for each of the inputs and outputs you'd like to use in the tool. This process is the same as it would be with a Python script tool. In those parameters, you can define the workspace, n and m values, and the output shapefile. If you are restricting this tool to just use Shapefiles, you can just pass around a reference to the Shapefile input, the .dbf and .prj files are part of the format. So I'd pass in just the Shapefile name, then if you need for example, the path to the DBF, you can run something like:
shape.root <- tools::file_path_sans_ext(input.shapefile) # extract name without .shp shape.dbf <- paste(shape.root, '.dbf', sep='')
shape.prj <- paste(shape.root, '.prj', sep='')
That way, your tool will have less inputs required. Once you've created your GP script with the necessary inputs and outputs, you can pass them directly to R as shown in this vignette Using the R-ArcGIS Bridge: the arcgisbinding Package, under the "Wrapping R Tool Functionality" section. Assign each one to a parameter, and the bridge will convert it to an appropriate type -- you only really have two things from the R side, paths as strings (shape and working directory) and integers. If you need further examples of how to build something like this, I recommend looking at the sample tools provided here:
GitHub - R-ArcGIS/r-sample-tools: Sample tools illustrating R usage in geoprocessing scripts
If you examine those tools, you'll see the parameters they set up, and how they are pulled in on the R side in the R scripts. As is the case with Python scripts, building fully generic tools from scripts does take a little bit of work, but I think its a worthwhile investment in your skillset.
Cheers,
Shaun
Thank shaun for the reply. But I think I figure that out. This is how I did it. Even though it is messy, it is working !!
tool_exec <- function(in_params, out_params)
{
# load the required packages
cat(paste0("\n", "Loading packages...", "\n"))
library(arcgisbinding)
arc.check_product()
# read input and output parameters
folder_path=in_params[[1]]# folder path
shp_name=in_params[[2]] # input shapefile name
n=as.integer(in_params[[3]])# write in how many random sites you want selected
m=as.integer(in_params[[4]])#write in how many "contingency" random sites
out_shp=in_params[[5]] # output shapefile name
setwd(folder_path)# shapefile path
extension <- ".dbf"
dbfFile = paste (shp_name,extension,sep="")# concatnate
library(spsurvey)
att <- read.dbf(dbfFile) # write in the name of your
# random point shapefile and add the file
# extension .dbf
att$stratum <- rep("Study", nrow(att))
dsgn <- list("Study"=list(panel=c(Base=n),
seltype='Equal',
over=m))
set.seed(3216530) # Do not need to change. But if you keep it constant
#it will allow you to redo the sample and get the same sites.
sites <- grts(design=dsgn,
DesignID='watershed',
SiteBegin=1, # default so can leave out
type.frame='finite',
src.frame='shapefile', # default so can leave out
in.shape=shp_name,
att.frame=att,
stratum='stratum',
mdcaty='MDCATY',
shapefile=TRUE,
out.shape=out_shp, #Name your output shape file
prjfilename=shp_name) #Copy same name as in.shape
#Done! Go and open the new point shapefile in ArcGIS.
cat(paste0("\n", "Done.", "\n"))
}
load_pkgs <- function(pkgs) {
new_pkgs = pkgs[(pkgs %in% installed.packages()[ ,'Package'])]
if (length(new_pkgs) > 0) install.packages(new_pkgs)
invisible(lapply(pkgs, function(x)
suppressMessages(library(x, character.only = TRUE)))
)
}
Looks good! Note that the random seed might be something you want to expose as a parameter as well, if you want each iteration to be randomized. As is (hard-coded seed), this will always produce the same output for the same input.
Good point. Thanks Shaun !!