providing R script templates with my package and open them easily - r

I have some script I want to provide to the user together with my package.
The normal way is to put them into the inst folder.
My problem is now. I want to allow the user to copy the script into the local directory so he can make changes on the default settings and execute the script locally.
Is there a comfortable way to open these provided scripts? Can I create links to the script within the package vignettes? Or has anyone a better solution instead of using a complicated command like this
file.copy(system.file('test.R','MyPackage'), '.')
Specially in this case, the user has to know the script name.
Thanks for any kind of suggestion.

Related

Is there a way to look at previous versions of code in an R Statistics file?

Is there a way to look back at previous code in a file? For instance maybe be able to revert to an earlier saved version or somehow see changes the file code went through?
Short answer: no.
Unless your changes are tracked in some sort of source control (like git) or you keep backups of your files, there is no way to see previous version of a script file. A .R script is just plain text files. They do not store their own history just like other documents or images on your computer don't either. Sorry.
If that's something you want to do in the future, Rstduio makes it easy to integrate with git. Check out this guide to Connect RStudio to Git and GitHub

Relative paths in R: how to avoid my computer being set on fire?

A while back I was reading an article about improving project workflow. The advice was not to use setwd or my computer would burn:
If the first line of your R script is
setwd("C:\Users\jenny\path\that\only\I\have")
I will come into your office and SET YOUR COMPUTER ON FIRE 🔥.
I started using the here package and it worked great until I started to schedule scripts using cronR. After asking this question my laptop was again threatened with arson:
If the first line of your #rstats script is wd <- here(), I will come
into your lab and SET YOUR COMPUTER ON FIRE.
Fearing for my laptop's safety I started using the method suggested in the answer to get relative file paths:
wd <- Sys.getenv("HOME")
wd <- file.path(wd, "projects", "my_proj")
Which worked for me but not people I was working with who didn't have the same projects directory. So now I'm confused. What is the safest / best way get relative file paths so that a project can be portable?
There are quite a few options: 1, 2. My requirements are to source functions/scripts and read/write csv files. Perhaps the rprojroot package is the best bet?
Create an RStudio project and then reference all files with relative paths from the project's root folder. That way, all users will open the project and automatically have the correct working directory.
There are many ways to organize code and data for use with R. Given that the "arsonist" described in the OP has rejected at least two approaches for locating the project files in an R script, the best next step is to ask the arsonist how s/he performs this function, and adjust your code and file structures accordingly.
UPDATE: Since the "arsonists" appear to be someone who writes on Tidyverse.org (see Tidyverse article in OP) and an answer on SO (see additional links in OP), your computer appears to be relatively safe.
If you are sharing code or executing it with batch processes where the "user" is someone other than you, a useful approach is to place the code, data, and configuration under version control, and develop a runbook to explain how others can retrieve the components and execute them on another computer.
As noted in the comments to the OP, there's nothing wrong with here::here() if its use can be made reliable through documentation in a runbook.
I structure all of my R code into Projects within RStudio, which are organized into a gitrepositories directory. All of the projects can be accessed as subdirectories from the gitrepositories directory. If I need to share a project, I make the project accessible to other users on GitHub.
In my R code I reference external files as subdirectories from the project root directory, such as ./data/gen01.csv.
There are two parts to this question:
how to load data from a relative path, and
how to load code from a relative path
For most use cases (including when invoking tools from a CRON job or similar) the location of the data should either be specified by the user (via command line arguments, standard input or environment variables) or should be relative to the current working directory (getwd() in R).
… Unless the data is a fixed part of the project itself — more on this below.
Loading code from a path that’s relative to other code is simply not supported by base R. For example, source('xyz.r') won’t source an xyz.r file from the project. It will always try to load it from the current working directory, whatever that happens to be. Which is pretty much never what you want. And as you’ve noticed, the ‘here’ package also doesn’t always work.
R basically only works when code is only loaded from packages. But packages aren’t suitable for all types of projects. R has no built-in solution for those other cases. I recommend using ‘box’ modules to solve this. ‘box’ provides a modern module system for R, which means that you can have R projects consisting of multiple code files (and nested sub-projects), without having to wrap them in packages. Loading code inside the same relative path in a module is as simple as
box::use(./xyz)
This always works, as you’d expect from a modern module system, and doesn’t require ‘here’ or similar hacks.
OK, back to the point about data that’s bundled with a project itself. If your project is an R package, you’d use system.file() to load that data. However, this once again doesn’t work for non-package projects. But if you use ‘box’ modules to structure your project, you can use box::file() to load data that’s associated with a module.
Packages such as ‘here’ or ‘rprojroot’, while well-intended, are essentially hacks to work around limitations in R’s handling of non-package code. The proper solution is to make non-package code into a first-class citizen of the R world, and ‘box’ does that.
You can check docs of RSuite package (https://RSuite.io). It is working with script_path that points to currently run R script. I use it to make relative paths using 'file.path' command

Load Folder of Scripts in R at startup?

I'm new to R and frankly the amount of documentation is overwhelming, and I haven't been able to find the answer to this question.
I have created a number of .R script files, all stored in a folder that I can access on my server (let's say the folder is, using the Windows backslash character \\servername\Paige\myscripts)
I know that in R you can call each script individually, for example (using the forward slash required in R)
source(file="//servername/Paige/myscripts/con_mdb.r")
and now this script, con_mdb, is available for use.
If I want to make all the scripts in this folder available at startup, how do I do this?
Briefly:
Use your ~/.Rprofile in the directory found via Sys.getenv("HOME") (or if that fails, in R's own Rprofile.site)
Loop over the contents of the directory via dir() or list.files().
Source each file.
as eg via this one liner
sapply(dir("//servername/Paige/myscripts/", "*.r"), source)
but the real story is that you should not do this. Create a package instead, and load that. Bazillion other questions here on how to build a package. Research it -- it is worth it.
Far the best way is to create a package! But as first step, you could also create one r script file (collection.r) in your script directory which includes all the scripts in a relative manner.
In your separate project scripts you can than include only that script with
source(file="//servername/Paige/myscripts/collection.r", chdir = TRUE)
which changes the directory before sourcing. Therefore you would have only to include one file for each project.
In the collection file you could use a loop over all files (except collection.r) or simply list them all.

Storing odbc connections centrally

We have several databases that we access, and different scripts require one or more of these odbcconnections. I wanted to know if instead of putting an odbcConnect line in every script if there was a method to store all the connections centrally and import them as needed? That way if the database info changes I can update one file instead of every script.
You could use options in your .Rprofile file to save the connections. In your scripts, you would then use getOption.
There is also a Rprofile.site file which might be a better choice if you are working in a team with several R installations.
See here or the R installation and administration handbook for more information.
What I ended up doing was creating a package with each connection as a function.

opening and changing wp-config file with bash script in nano

I’ve created or rather copied from a number of sources the necessary pieces in order to create my own bash script that will install WP via ssh. I’m not a coder at all, so many things will go over my head. But my patience and desire to learn will compensate.
I’ve created a bash script to download wordpress, create a new database (with correct permissions) then open the wp-config-sample.php file, rename it to wp-config.php file then open it up using nano. This is where I’m stuck. I’d like to use the details from the newly created database and have those details automatically inserted into the correct places within the wp-config file. Then I’d like to visit this url (https://api.wordpress.org/secret-key/1.1/salt/) and take those salt keys and also save them in the same wp-config.php file then save and quit.
Please help!
I don't think nano is going to be scriptable in the manner you need.
You need to look into Templates. The general idea is to put placeholders like %DB_NAME%, %DB_USER%, inside a template file like wp-config-template.php. Then you can use something like sed to search and replace these placeholders with real values, to generate the final wp-config.php.
However doing this in sed will get messy pretty quickly. You are better of using a scripting language like perl or python when you start doing templating. They will do the heavy lifting for you.
Finally, not to discourage your efforts. But building a server like you are is tricky, because there are number of things that could go wrong. Also you need to be idempotent, ie:- the ability to rerun your entire set of scripts, and only applying changes. So if you decide to add/remove packages the rest of the system should remain untouched.
If you are looking for a good guideline containing some the best tools to do this, you should check out the Genesis-WordPress project. It uses Ansible for provisioning and Capistrano for deployment.
Good Luck!
If you want a disgusting, but functional example on how to change wp-config.php from environmental variables in a bash script, check out the "official" WordPress scripts for creating a Docker image.

Resources