Documentation ¶
Overview ¶
Package arrgh provides an interface to R via an OpenCPU server.
Interaction with the OpenCPU system is via the OpenCPU API https://www.opencpu.org/api.html. Data serialisation and deserialisation at the R end is performed by jsonlite, see http://cran.r-project.org/web/packages/jsonlite/jsonlite.pdf for the jsonlite manual.
Example (Linear) ¶
package main import ( "bufio" "encoding/json" "fmt" "io" "log" "net/url" "os" "path" "path/filepath" "strings" "time" "github.com/kortschak/arrgh" ) func main() { r, err := arrgh.NewRemoteSession("http://public.opencpu.org", "", 10*time.Second) if err != nil { log.Fatal(err) } defer r.Close() // Send a query to get a session result for the linear // regression: coef(lm(speed~dist, data=cars)). resp, err := r.Post( "library/base/R/identity", "application/x-www-form-urlencoded", nil, strings.NewReader("x="+url.QueryEscape("coef(lm(speed ~ dist, data = cars))")), ) if err != nil { log.Fatal(err) } defer resp.Body.Close() // Get each part of the session result and display it, // keeping the location of the linear regression. sc := bufio.NewScanner(resp.Body) var val string for sc.Scan() { // API root path stripping here depends on consistency // between os.Separator and the URL path separator. p, err := filepath.Rel(r.Root(), sc.Text()) if err != nil { log.Fatal(err) } if path.Base(p) == ".val" { val = p } fmt.Printf("%s:\n", p) resp, err := r.Get(p, nil) if err != nil { log.Fatal(err) } io.Copy(os.Stdout, resp.Body) fmt.Print("\n\n") resp.Body.Close() } // Get the linear regression result as JSON. res, err := r.Get(path.Join(val, "json"), url.Values{"digits": []string{"10"}}) if err != nil { log.Fatal(err) } defer res.Body.Close() // Decode the result into a [2]float64. var lm [2]float64 dec := json.NewDecoder(res.Body) err = dec.Decode(&lm) if err != nil { log.Fatal(err) } fmt.Printf("lm: intercept=%f dist=%f\n", lm[0], lm[1]) }
Output:
Example (Local) ¶
package main import ( "encoding/json" "fmt" "log" "net/url" "os" "strings" "time" "github.com/kortschak/arrgh" ) func main() { r, err := arrgh.NewLocalSession("", "", 3000, 10*time.Second, os.Stderr) if err != nil { log.Fatal(err) } defer r.Close() // Send a query to get a JSON representation of results // from rnorm(n=10, mean=10, sd=10). resp, err := r.Post( "library/stats/R/rnorm/json", "application/json", url.Values{"digits": []string{"10"}}, strings.NewReader(`{"n":10, "mean": 10, "sd":10}`), ) if err != nil { log.Fatal(err) } defer resp.Body.Close() // Decode the results in to a slice of float64. var rnorm []float64 dec := json.NewDecoder(resp.Body) err = dec.Decode(&rnorm) fmt.Println(rnorm, err) }
Output:
Example (Upload) ¶
package main import ( "bytes" "io" "log" "os" "regexp" "time" "github.com/kortschak/arrgh" ) func mask(r io.Reader) io.Reader { re := regexp.MustCompile("x[0-9a-f]{10}") var buf bytes.Buffer io.Copy(&buf, r) return bytes.NewReader(re.ReplaceAll(buf.Bytes(), []byte("xXXXXXXXXXX"))) } func main() { r, err := arrgh.NewRemoteSession("http://public.opencpu.org", "", 10*time.Second) if err != nil { log.Fatal(err) } defer r.Close() // Upload the contents of the file "mydata.csv" and send // it to the read.csv function. f, err := os.Open("mydata.csv") if err != nil { log.Fatal(err) } content, body, err := arrgh.Multipart( arrgh.Params{"header": "FALSE"}, arrgh.Files{"file": f}, ) f.Close() if err != nil { log.Fatal(err) } resp, err := r.Post( "library/utils/R/read.csv", content, nil, body, ) if err != nil { log.Fatal(err) } defer resp.Body.Close() io.Copy(os.Stdout, mask(resp.Body)) }
Output: /ocpu/tmp/xXXXXXXXXXX/R/read.csv /ocpu/tmp/xXXXXXXXXXX/R/.val /ocpu/tmp/xXXXXXXXXXX/stdout /ocpu/tmp/xXXXXXXXXXX/source /ocpu/tmp/xXXXXXXXXXX/console /ocpu/tmp/xXXXXXXXXXX/info /ocpu/tmp/xXXXXXXXXXX/files/DESCRIPTION /ocpu/tmp/xXXXXXXXXXX/files/mydata.csv
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Files ¶
type Files map[string]NamedReader
Params is a collection of parameter names and file objects to be passed using Multipart.
type NamedReader ¶
NamedReader allows an io.Reader to be passed as a named data file object.
type Session ¶
type Session struct {
// contains filtered or unexported fields
}
Session holds OpenCPU session connection information.
func NewLocalSession ¶
func NewLocalSession(path, root string, port int, timeout time.Duration, log io.Writer) (*Session, error)
NewLocalSession starts an R instance using the executable in the given path or the executable "R" in the user's $PATH if path is empty. An OpenCPU server is started using the provided port and connection is tested before returning. If no connection is possible within the timeout, a nil session and an error are returned. The root of the OpenCPU API is set to "/ocpu" if it is left empty. The OpenCPU server's logs are written to log.
It is important that Close() be called on sessions returned by NewLocalSession.
func NewRemoteSession ¶
NewRemoteSession connects to the OpenCPU server at the specified host. The root of the OpenCPU API is set to "/ocpu" if it is left empty.
func (*Session) Close ¶
Close shuts down a running local session, terminating the OpenCPU server and the R session. It is a no-op on a remote session.
func (*Session) Get ¶
Get retrieves the given OpenCPU path using the GET method. The URL parameters specify GET parameters which are interpreted by jsonlite.
See https://www.opencpu.org/api.html#api-methods for details.
func (*Session) Post ¶
func (s *Session) Post(path, content string, params url.Values, query io.Reader) (*http.Response, error)
Post sends the query content to the given OpenCPU path as the specified content type using the POST method. The URL parameters specify additional POST parameters. These parameters are interpreted by jsonlite.
See https://www.opencpu.org/api.html#api-methods and https://www.opencpu.org/api.html#api-arguments for details.
Directories ¶
Path | Synopsis |
---|---|
paper
|
|
example/nuccore
The nuccore program summarises the lengths of sequences in the nuccore database in Entrez that are linked from genomes studies.
|
The nuccore program summarises the lengths of sequences in the nuccore database in Entrez that are linked from genomes studies. |