Is there a web-based R API that would allow calling different methods from a web-based app?
It really depends on what language you use for the front end and what the rest of the site will be like. For example, there are rinruby, rsruby and rserve that can be used in rails applications (an example is my site StudyDesignCalculators.com). rpy can be used with Django.
Shiny is good if you want everything to be in R, but for large websites, it is probable not optimal. Rserve is nice because you can use it with many front end languages.
Calling R as a web service with parameters and load a JSON?
If you have not done so yet please checkout [DeployR]. You can also post questions to the DeployR Google Group for help.
For full disclose I am one of the authors of DeployR
Overview
DeployR is an integration technology for deploying R analytics inside web, desktop,mobile,and dashboard applications as well as backend systems. DeployR turns your R scripts into analytics web services, so R code can be easily executed by applications running on a secure server.
Using analytics web services, DeployR also solves key integration problems faced by those adopting R-based analytics alongside existing IT infrastructure. These services make it easy for application developers to collaborate with data scientists to integrate R analytics into their applications without any R programming knowledge.
DeployR is available in two editions: DeployR Open and DeployR Enterprise. DeployR Open is a free, open source solution that is ideal for prototyping, building, and deploying non-critical business applications.
DeployR Enterprise scales for business-critical applications and offers support for production-grade workloads, as well as seamless integration with popular enterprise security solutions such as single sign-on (SSO), Lightweight Directory Access Protocol (LDAP), Active Directory, or Pluggable Authentication Modules (PAM).
I am pretty new with R
Prefect. DeployR is intended for both the Data Scientist as well as the application developer who might not know R.
What I am trying to do is to be able to load a URL from another application
(Java) which will run an R script and output a JSON so my application can work with it.
DeployR does this quit well. To aid in the communication between your application
and the DeployR server (that will be executing your R) there are the DeployR Client libraries.
Depending on your needs, DeployR has out-of-the-box 'client library' support in:
- Java-client-library:
https://github.com/deployr/java-client-library
- .NET-client-library:
https://github.com/deployr/dotnet-client-library
- JavaScript and Node.js-library:
https://github.com/deployr/js-client-library
DeployR also supports the RBroker Framework
should your use-case or runtime anticipate a high-volume workload or the need for periodic, scheduled or batch processing.
I understand there are some frameworks like shiny which act as web servers for
R, but I can't find documentation on those frameworks on how to pass parameters
via the URL so R can use them
DeployR acts as your analytics engine through its APIS. Basically think of it as
turning your R scripts into secure analytic web services to be consumed like any
other web service.
Pass parameters
Passing parameters to an R Script in DeployR is easy, however you have to understand that you are passing parameters to an R Script from a language that is not R. As such, there is some 'Data Encoding' that needs to be done. For example, turn your Java String into an R character
or your Java boolean to an R logical
...
The DeployR Client library or RBroker makes this easy.
It sounds like you are using Java, so first review the Java tutorial java-example-client-basics https://github.com/deployr/java-example-rbroker-basics
to give you some context then checkout the many Java examples under java-example-client-data-io https://github.com/deployr/java-example-client-data-io
.
The example source is fully available so that should give you everything you need
in order to understand how to do basic I/O from your application to the DeployR server for your R analytics.
Ideally I will need to call a URL like:
http://127.0.0.1/R/param1/param2
I suggest using the DeployR Client libraries for your communication as described above, it does just that.
As always post questions to the DeployR Google Group https://groups.google.com/forum/#!forum/deployr
for help.
Integration between R and php
There are several options, but one option is to use RApache.
Install RApache as indicated in http://rapache.net/manual.html
Set the Apache directive in httpd.conf which will make sure all files under /var/www/brew are parsed as R scripts
<Directory /var/www/brew>
SetHandler r-script
RHandler brew::brew
</Directory>
Make your R script with your API with file name plot.R and put it under the /var/www/brew folder. This R script file can e.g. look as follows:
<%
library(rjson)
args <- GET
tmp <- lapply(args, FUN=function(x) strsplit(x, " "))
typeOfData <- tmp[[1]][1]
month <- tmp[[2]][1]
year <- tmp[[3]][1]
output <- list(imgname="imgs/tmax.tiff")
cat(toJSON(output))
%>
Mark the GET
Now you can call your API from PHP as you would call any other webservice by calling http://localhost/brew/plot.R?typeOfData=1&month=2&year=2014
. Replace localhost with the IP of the server where you are hosting the API.
When using RApache, each time you get GET, POST, COOKIES, FILES, SERVER
variables which were passed on to the API call. So if you want to use POST in your call instead of the GET example, go ahead. See the documentation in http://rapache.net/manual.html for these variables.
This is almost the same answer as indicated here: What's the easiest way to deploy an API incorporating R functions?
Integrate function with more than one variable
You don't have to pass the name of the function with its argument in it, R is looking for the object a
and can't find it. You also need to provide a value for b
. This works:
f <- function(a,b) {a^2 + a*b^2}
integrate(f, lower = 0, upper = 1, b = 5)
What is the best way to pass a list of functions as argument?
Simplifying solutions in question
The first of the solutions in the question requires that the list be named and the second requires that the functions have names which are passed as character strings. Those two user interfaces could be implemented using the following simplifications. Note that we add an envir
argument to foo2
to ensure function name lookup occurs as expected. Of those the first seems cleaner but if the functions were to be used interactively and less typing were desired then the second does do away with having to specify the names.
foo1 <- function(input, funs) Map(function(f) f(input), funs)
foo1(1:5, list(min = min, max = max)) # test
foo2 <- function(input, nms, envir = parent.frame()) {
Map(function(nm) do.call(nm, list(input), envir = envir), setNames(nms, nms))
}
foo2(1:5, list("min", "max")) # test
Alternately we could build foo2
on foo1
:
foo2a <- function(input, funs, envir = parent.frame()) {
foo1(input, mget(unlist(funs), envir = envir, inherit = TRUE))
}
foo2a(1:5, list("min", "max")) # test
or base the user interface on passing a formula containing the function names since formulas already incorporate the notion of environment:
foo2b <- function(input, fo) foo2(input, all.vars(fo), envir = environment(fo))
foo2b(1:5, ~ min + max) # test
Optional names while passing function itself
However, the question indicates that it is preferred that
- the functions themselves be passed
- names are optional
To incorporate those features the following allows the list to have names or not or a mixture. If a list element does not have a name then the expression defining the function (usually its name) is used.
We can derive the names from the list's names or when a name is missing we can use the function name itself or if the function is anonymous and so given as its definition then the name can be the expression defining the function.
The key is to use match.call
and pick it apart. We ensure that funs
is a list in case it is specified as a character vector. match.fun
will interpret functions and character strings naming functions and look them up in the parent frame so we use a for
loop instead of Map
or lapply
in order that we not generate a new function scope.
foo3 <- function(input, funs) {
cl <- match.call()[[3]][-1]
nms <- names(cl)
if (is.null(nms)) nms <- as.character(cl)
else nms[nms == ""] <- as.character(cl)[nms == ""]
funs <- as.list(funs)
for(i in seq_along(funs)) funs[[i]] <- match.fun(funs[[i]])(input)
setNames(funs, nms)
}
foo3(1:5, list(mean = mean, min = "min", sd, function(x) x^2))
giving:
$mean
[1] 3
$min
[1] 1
$sd
[1] 1.581139
$`function(x) x^2`
[1] 1 4 9 16 25
Related Topics
How to Create a Variable of Rownames
Navlistpanel: Make Tabs Sequentially Active in Shiny App
How to Install R-Packages Not in the Conda Repositories
How Is Data Passed from Reactive Shiny Expression to Ggvis Plot
Determine Season from Date Using Lubridate in R
How to Add Gaussian Curve to Histogram Created with Qplot
Linear Model with 'Lm': How to Get Prediction Variance of Sum of Predicted Values
Simple R 3D Interpolation/Surface Plot
Using Pivot_Longer with Multiple Paired Columns in the Wide Dataset
Create Link to the Other Part of the Shiny App
Ggplot Geom_Bar: Stack and Center
Open Hyperlink on Click on an Ggplot/Plotly Chart
How to Write Special Characters in Rmarkdown Latex Documents
As_Labeller with Expression() in Ggplot2 Facet_Wrap
Plot Linear Regressions Lines Without Interaction in Ggplot2