21

I'm trying to port some packages to an R installation on an offline (Windows) computer.

From CRAN (let's say data.table), the process: 1) download .zip on separate online computer 2) thumb drive -> offline computer 3) install via install.packages("....zip"...) works exactly as expected.

However, this process broke down when I tried to install from GitHub.

When I run install.packages (note: I'm using type="binary" and repos=NULL; type="win.binary" does nothing either) on the zip file (obtained by going to the package page, e.g. https://github.com/Rdatatable/data.table, and using the "Download .zip" function), something goes wrong.

There's no error message (and nothing new from setting verbose=TRUE), and the package folder is added to my library (i.e., I can see the folder named "data.table-master" when I navigate there), but library(data.table) results in the error: "there is no package called data.table". I also noticed that, while the installation from CRAN finishes with "package data.table successfully unpacked and MD5 sums checked", I get no such message from an attempted GitHub installation.

What's going on here? I tried all possible leads in ?install.packages, but given I'm not really getting an error message it's been hard to diagnose what exactly is the issue.

More background: R version is 3.2.0. Hard to copy-paste sessionInfo since that computer's not online, not sure what else may be relevant.

Update:

Given @r2evans' comments below, I also tried using type="source" with install.packages, and this didn't work either (same problem--despite having "data.table-master" folder in one of my .libPaths() addresses, library(data.table) gives the error that there's no such package).

I did get some more output from using verbose=TRUE this time, however:

system (cmd0): C:/PROGRA~1/R/R-32~1.0/bin/x64/R CMD INSTALL

1): succeeded 'C:/PROGRA~1/R/R-32~1.0/bin/x64/R CMD INSTALL -l "C:\Users\Mike\Documents\R\win-library\3.2" "E:/data.table-master.zip"'

Community
  • 1
  • 1
MichaelChirico
  • 33,841
  • 14
  • 113
  • 198
  • 1
    Aren't packages downloaded from GH in "source" form, not "binary"? – r2evans Oct 17 '15 at 05:37
  • @r2evans I'll have to try that out. I can't say I understand the difference well, given both CRAN and GH produce .zip folders. My initial pass was to use `type="both"` but this is an error when `repos="NULL"`, so I wouldn't have caught this. – MichaelChirico Oct 17 '15 at 15:00
  • *R* typically distributes binary packages in `zip` files and source packages in `tar.gz` files, but that does not mean that everything distributed in a `zip` file is a binary package. Look at another package (not from GH) in both formats and see the difference internally. – r2evans Oct 17 '15 at 15:07
  • Thanks for the suggestion @r2evans; see update. No luck, but I at least got some feedback from setting `verbose=TRUE` this time. – MichaelChirico Oct 17 '15 at 19:04
  • I got it to work by unzipping it and repacking it as a `tar.gz` (obviously just renaming it isn't enough). From there, as long as all the dependencies are met (e.g., `chron`), it compiled and installed correctly. – r2evans Oct 17 '15 at 19:28
  • @r2evans what tool do you use to pack as tar.gz on windows? – MichaelChirico Oct 17 '15 at 22:50
  • I use `tar`, from any one of [msys2](https://msys2.github.io/), [cygwin](https://www.cygwin.com/), [git-for-windows sdk](https://git-for-windows.github.io/) (most of which are overkill), or perhaps [gnuwin32](http://gnuwin32.sourceforge.net/). There are plenty of other graphical utilities, if you google it. – r2evans Oct 17 '15 at 22:59
  • @r2evans I used http://www.zamzar.com/ and this failed miserably; what options did you use in the installation? I'm getting either "status 1" from `R CMD INSTALL`... or "cannot open compressed file .../`DESCRIPTION`, probably reason 'No such file or directory'" even though the file is clearly in the compressed folder. – MichaelChirico Oct 17 '15 at 23:00
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/92610/discussion-between-r2evans-and-michaelchirico). – r2evans Oct 17 '15 at 23:16
  • 1
    downloading a zip from github is just a compressed folder with the files in the repo. `install_github` downloads those and installs from source (which is why you must also have the development tools installed for this to work). perhaps confusingly, when building from windows (binary) you also get a .zip file which _can_ be used to install packages because those files have been through R CMD build/R CMD check, but those are not the same .zip files you git from gethub. Is that the gist of the question? – rawr Feb 24 '16 at 20:51
  • @rawr as I understand it, yes. In essence, though, I really just want a way to get GH-only packages onto an offline computer. My approach thus far has been to download the zip and put it to a thumb drive, then try to install from that downloaded zip. – MichaelChirico Feb 24 '16 at 20:58
  • 2
    @MichaelChirico that will work for binary .zip packages. for source .tar.gz or a folder from github, you need to install r tools or whatever is necessary to build r packages for a particular platform – rawr Feb 24 '16 at 20:59
  • @rawr I thought I had installed R tools, but I'll have to confirm that when I get back to the secure data room. – MichaelChirico Feb 24 '16 at 21:00
  • @rawr thanks for hitting me over the head again with RTools, I don't know why I convinced myself I'd installed it. I suppose that means you earned the bounty -- add the Rtools thing to that an advisory note about setting `PATH` ([this](http://stackoverflow.com/a/29480538/3576984) answer was slightly wrong -- I needed to add both C:\Rtools\bin\ _and_ C:\Rtools\gcc-4.6.3\bin\ to get things to work) and answer if you want. Also restarting _within_ RStudio didn't work (possible bug?) -- I had to close and re-open RStudio to get `Sys.getenv()["PATH"]` to reflect what I'd added in the Control Panel. – MichaelChirico Feb 26 '16 at 16:54

5 Answers5

21

Let's assume that you have Rtools and devtools on the win machine.

Step 1: Download the source zip.

Step 2: Copy to the win machine and unzip the content there.

Step 3: Run the following code (adjust the path as necessary):

library(devtools)
source <- devtools:::source_pkg("E:/temp/data.table-master")
install(source)

library(data.table)
#loads 1.9.7
Roland
  • 127,288
  • 10
  • 191
  • 288
  • Well silly me, it appears RTools was the source of the issue after all. What's the point of `source_pkg`? I was able to just run `install.packages("F:\\path\\to\\package\\", repos = NULL, type = "source")`. I ask because `devtools` has a litany of dependencies, each of which is a pain to install on an offline machine.... is there something to be gained by going through the extra hooplah to get `devtools`? – MichaelChirico Feb 26 '16 at 16:50
  • 1
    I was giving an alternative since you claimed that `install.packages` didn't work for installing from source (I hadn't tried). Good for you that you solved this. – Roland Feb 26 '16 at 19:53
9

You can use install_local from devtools to install a Github package with the zip you've downloaded, e.g. :

library("devtools")
install_local(path = "data.table-master.zip")

But you'll have to install all dependancies first.

Victorp
  • 13,636
  • 2
  • 51
  • 55
7

Not sure if this is a solution or a workaround. Given a zip file of the source of an R package directory structure:

On a shell:

~$ unzip data.table-master.zip
## optional renaming
~$ mv data.table-master data.table
## create the new
~$ tar czf data.table.tar.gz data.table

There are likely other tools that allow you to extract and re-archive them in a different format. Since I tend towards shell-level access and control, I tend towards these simple tools.

In R:

install.packages("data.table.tar.gz", type="source", repos=NULL)

(This will not succeed unless all dependencies are already installed.)

r2evans
  • 141,215
  • 6
  • 77
  • 149
  • just to be clear (since I'm not at a computer to test right now) you're suggesting I download the zip from a Linux (or other terminal-friendly machine), re-tar it from the command line, then transfer this recompressed file to the offline computer and install as `"source"`? thanks for your help thus far by the way! – MichaelChirico Oct 18 '15 at 03:31
  • This approach failed for me; "running command `"C:/PROGRA~1/R/R-32~1.0/bin/x64/R" CMD INSTALL -l "C:\Users\Mike\Documents\R\win-library\3.2" "E:/data.table.tar.gz"` had status 1"; [this](http://stackoverflow.com/questions/26169358/how-to-install-tar-gz-r-package-with-non-zero-exit-status) question I found seems to suggest the solution is to re-convert the file to a zip TT – MichaelChirico Oct 18 '15 at 23:34
3

The following function extracts a GitHub .zip file located at path to a temporary directory and installs the package straight from there, i.e. does not create an interim .tar.gz archive. The function tries to guess the package name but it can also be given through pkg. Temporary files are removed at exit.

This function does not install any dependencies.

install_zip <- function(path,
                        pkg = sub("(-[^-]+)?\\.[^.]+$", "", basename(path))) {
    dir1 <- tempfile()
    dir2 <- file.path(dir1, pkg)
    dir.create(dir2, recursive = TRUE)
    on.exit(unlink(dir1, recursive = TRUE, force = TRUE))
    suppressMessages(unzip(path, exdir = dir2,
                           unzip = getOption("unzip")))
    temp_contents <- dir(dir2)
    if (length(temp_contents) == 1L) {
        dir3 <- file.path(dir2, temp_contents)
        if (file.info(dir3, extra_cols=FALSE)[["isdir"]]) {
            dir2 <- file.path(dir2, pkg)
            file.rename(dir3, dir2)
        }
    }
    install.packages(dir2, repos = NULL, type = "source")
}
mvkorpel
  • 526
  • 6
  • 10
2

So I've finally come up with a workaround that works in some cases... but it's admittedly a bit macgyvered. Would love to hear some feedback about how to make this approach work for any package.

Since I have a package where all of the code is in one .R file, I spoofed a package environment for that package and sourced the functions into that environment. Suppose the package is all in test.R:

#add an appropriately named package to the search() path
attach(environment(), name = "package:pkg")

#source the functions
sys.source("test.R", envir = as.environment("package:pkg"))

Voila. I don't know enough about how packages are loaded to say how to do this, for example, if the package has src code in C or something else.

MichaelChirico
  • 33,841
  • 14
  • 113
  • 198