A simple change in the example vignette from this site illustrates my problem.
The code below will run. No problem. Because there is no whitespace in the url.
#miniCRAN example
library("miniCRAN")
# use Revolution Analytics CRAN mirror
revolution <- c(CRAN = "http://cran.microsoft.com")
# Specify list of packages to download
pkgs <- c("foreach")
pkgList <- pkgDep(pkgs, repos = revolution, type = "source", suggests = FALSE)
pkgList
# Create temporary folder for miniCRAN
dir.create(pth <- file.path("C:", "RTEMP", "miniCRAN"), recursive=TRUE)
# Make repo for source and win.binary
makeRepo(pkgList, path = pth, repos = revolution, type = c("source", "win.binary"))
# List all files in miniCRAN
list.files(pth, recursive = TRUE, full.names = FALSE)
#install packages from your local repository
install.packages(pkgs, repos = paste0("file:///", pth), type = "source")
But if we change the following line so it has a space character, then it will fail on install.packages.
# Create temporary folder for miniCRAN
dir.create(pth <- file.path("C:", "WHITE SPACE", "miniCRAN"), recursive=TRUE)
Looks to me like the pth string gets split up. Is there any way around this, other than changing folder names in my filesystem? I tried to replace " " with "%20" but that did not help. I am on a Windows system, btw.
Warning: invalid package 'C:/WHITE'
Warning: invalid package 'SPACE/miniCRAN/src/contrib/foreach_1.4.4.tar.gz'
Error: ERROR: no packages specified
Firstly, I think file.path("C:", "WHITE SPACE", "miniCRAN") is not valid path, because there's no slash after C:.
Anyway, to use install.packages with a path containing white spaces, use shortPathName:
shortPathName(file.path("C:/", "WHITE SPACE", "miniCRAN"))
Related
According to RStudio:
In addition, certain functions, such as library() and require(), expect package names for completions. RStudio automatically infers whether a particular function expects a package name and provides those names as completion...
My question is: how? I'm writing a custom function that takes package names as arguments, yet RStudio's only completing the arguments with object & function names, and I can't tell what it is about the library() and require() code that RStudio is picking up on.
My function is:
unpack <- function(...,
lib = NULL,
repos = getOption("repos")) {
pkgs <- sapply(match.call(expand.dots = TRUE)[-1], as.character)
new.pkgs <-
pkgs[!(
pkgs %in% installed.packages(lib.loc = lib)[, "Package"]
)]
if (length(new.pkgs))
install.packages(new.pkgs,
lib = lib,
repos = repos)
sapply(pkgs, require,
lib.loc = lib,
character.only = TRUE)
}
As #hrbrmstr pointed out, there's both Java and R code that specifically name the four functions that autocomplete with package names, so the solution is to either mask one of those and cross your fingers, or add your function's name to those lists in both source files (or maybe just the R, I wonder).
I recently created a package which has few more autocompletion (though totally experimental) (as extra code only).
It can be seen here https://github.com/r-rudra/patch/blob/main/inst/embedded/usecases.R
Maybe soon enough all these will be available by default in RStudio.
Check this comment
When running install.packages("any_package") on windows I get the message :
trying URL
'somepath.zip'
I would like to get this path without downloading, is it possible ?
In other terms I'd like to get the CRAN link to the windows binary of the latest release (the best would actually be to be able to call a new function with the same parameters as install.packages and get the proper url(s) as an output).
I would need a way that works from the R console (no manual checking of the CRAN page etc).
I am not sure if this is what you are looking for. This build the URL from the repository information and building the file name of the list of available packages.
#get repository name
repos<- getOption("repos")
#Get url for the binary package
#contrib.url(repos, "both")
contriburl<-contrib.url(repos, "binary")
#"https://mirrors.nics.utk.edu/cran/bin/windows/contrib/3.5"
#make data.frame of avaialbe packages
df<-as.data.frame(available.packages())
#find package of interest
pkg <- "tidyr" #example
#ofinterest<-grep(pkg, df$Package)
ofinterest<-match(pkg, df$Package) #returns a single value
#assemble name, assumes it is always a zip file
name<-paste0(df[ofinterest,]$Package, "_", df[ofinterest,]$Version, ".zip")
#make final URL
finalurl<-paste0(contriburl, "/", name)
Here's a couple functions which respectively :
get the latest R version from RStudio's website
get the url of the last released windows binary
The first is a variation of code I found in the installr package. It seems there's no clean way of getting the last version, so we have to scrape a webpage.
The second is really just #Dave2e's code optimized and refactored into a function (with a fix for outdated R versions), so please direct upvotes to his answer.
get_package_url <- function(pkg){
version <- try(
available.packages()[pkg,"Version"],
silent = TRUE)
if(inherits(version,"try-error"))
stop("Package '",pkg,"' is not available")
contriburl <- contrib.url(getOption("repos"), "binary")
url <- file.path(
dirname(contriburl),
get_last_R_version(2),
paste0(pkg,"_",version,".zip"))
url
}
get_last_R_version <- function(n=3){
page <- readLines(
"https://cran.rstudio.com/bin/windows/base/",
warn = FALSE)
line <- grep("R-[0-9.]+.+-win\\.exe", page,value=TRUE)
long <- gsub("^.*?R-([0-9.]+.+)-win\\.exe.*$","\\1",line)
paste(strsplit(long,"\\.")[[1]][1:n], collapse=".")
}
get_package_url("data.table")
# on my system with R 3.3.1
# [1] "https://lib.ugent.be/CRAN/bin/windows/contrib/3.5/data.table_1.11.4.zip"
In Revolution R Enterprise console,
devtools::check("C:/Users/User/Documents/Revolution/mypackage")
produced
checking sizes of PDF files under 'inst/doc' ... NOTE
Unable to find GhostScript executable to run checks on size reduction
with no any other warnings/errors/notes. So, (even though AFAIK this note is not that much important for eventual check), I wanted to get rid of this warning (since I wanna put .PDF files into mypackage\inst\doc folder produced outside of R).
I have Ghostscript installed in my notebook. I got helped via:
> help("R_GSCMD")
R_GSCMD: Optional. The path to Ghostscript, used by dev2bitmap, bitmap and embedFonts.
Consulted when those functions are invoked.
Since it will be treated as if passed to system, spaces and shell metacharacters should be escaped.
> Sys.getenv("R_GSCMD")
[1] ""
What I did (and took error again) is:
> Sys.setenv("R_GSCMD") <- "C:\\Program Files (x86)\\gs\\gs9.19\\bin\\gswin32c.exe"
Error in Sys.setenv("R_GSCMD") <- "C:\\Program Files (x86)\\gs\\gs9.19\\bin\\gswin32c.exe" :
target of assignment expands to non-language object
Upon deepening, I found: ["These errors occur when one tries to assign a value to a variable that doesn't exist, or that R can't treat as a name. (A name is a variable type that holds a variable name."]
What I am basically trying to do is to set my GS executable (C:\Program Files (x86)\gs\gs9.19\bin\gswin32c.exe) to "R_GSCMD".
Any help would be greatly appreciated.
On consulting ?Sys.setenv it confirms my expectation that the call should instead be:
Sys.setenv(R_GSCMD = "C:\\Program Files (x86)\\gs\\gs9.19\\bin\\gswin32c.exe")
Because the gs versions change all the time, you may like a little R script for it!
system.partition = 'c:'
dirs = c('Program Files', 'Program Files (x86)')
for (dir in dirs) {
dir.list = list.dirs(file.path(system.partition, dir), recursive = FALSE)
GsinList = grepl(pattern = 'gs', x = dir.list)
if (sum(GsinList) > 0) {
gsDirectory = which(GsinList == TRUE)
GsExeFiles = list.files(
dir.list[gsDirectory],
recursive = TRUE,
pattern = 'gswin',
include.dirs = TRUE,
full.names = TRUE
)[1]
message('Gs found! ~> ',GsExeFiles)
Sys.setenv(R_GSCMD = GsExeFiles)
break
}
}
Gs found! ~> c:/Program Files/gs/gs9.21/bin/gswin64.exe
My server.R contains the following code for dynamically installing packages when needed:
package <- input$chip
if (!require(package, character.only=T, quietly=T)) {
source("https://bioconductor.org/biocLite.R")
biocLite(package, ask = F, suppressUpdates = T, suppressAutoUpdate = T)
library(package, character.only=T)
}
ui.R has a select input element where the user can select one of the following bioconductor packages:
selectInput(inputId = 'chip', label='Chip', choices=c('Mouse Gene 1.0'='mogene10sttranscriptcluster.db',
'Mouse Gene 2.0'='mogene20sttranscriptcluster.db',
'Human Gene 1.0'='hugene10sttranscriptcluster.db',
'Human Genome U133A 2.0'='hgu133a2.db'))
So, based on what chip the user selects, the corresponding annotation package should get loaded, and if it is not already installed, it should install it.
This works on my local machine. But when I try to deploy my app on shinyapps.io. I get the following error:
Error:
* Application depends on package "package" but it is not installed. Please resolve before continuing.
I know that it is unable to recognize the package in biocLite(package, ask = F, suppressUpdates = T, suppressAutoUpdate = T). The deployment process thinks that package is a library name and not a variable and is unable to evaluate its value.
Is there any way to resolve this? Or do I have to explicitly load all required packages? The problem with explicitly loading the annotation packages is that these packages are so big they take up a lot of memory, which is why I wanted to load these packages only when required.
An alternative is to make an if-else loop or switch statement to install packages based on the condition:
package <- function(input$chip) {
switch(input$chip,
'mogene10sttranscriptcluster.db' = 'mogene10sttranscriptcluster.db',
'mogene20sttranscriptcluster.db' = 'mogene20sttranscriptcluster.db',
'hugene10sttranscriptcluster.db' = 'hugene10sttranscriptcluster.db',
'hgu133a2.db' = 'hgu133a2.db')
}
library(package)
But even in this case, the deployment process won't be able to evaluate the package value.
Thanks!
UPDATE:
Taking Yihui's suggestion, I modified my code to:
package <- input$genome
if(!do.call(require, list(package = package, character.only = T, quietly = T))){
do.call(biocLite, list(pkgs = package, ask = F, suppressUpdates = T, suppressAutoUpdate = T))
do.call(library, list(package = package, character.only = TRUE))
}
The application is able to deploy now, but it throws me this error:
Error: unable to install packages
Unfortunately, you have to fool the shinyapps (or rsconnect) package a bit so that it does not detect package as a literal package name. For example, you may use do.call():
do.call(library, list(package = package, character.only = TRUE))
The ShinyApps.io server does not allow you to install packages on the fly (strictly speaking, this is not true, but I don't want to show you how). You have to declare all packages you need in the app as dependencies beforehand. Again, it is a hack:
if (FALSE) {
library(mogene10sttranscriptcluster.db)
library(mogene20sttranscriptcluster.db)
library(hugene10sttranscriptcluster.db)
library(hgu133a2.db)
}
Then ShinyApps.io will detect these packages as dependencies and pre-install them for you. What you need to do in your app is simply load them, and you don't need to install them by yourself.
I using a CRAN package which contains a subdirectory "examples/" containing a file "ex.txt". How do I access this file?
I tried
require("XX")
read.table(paste(.path.package("XX"), "/examples/ex.txt", sep=""), header=TRUE, sep="\t")
but then the file is not found. When I look in the installation directory of the package, I indeed see no "examples/" subdirectory. However, when I run R CMD check and R CMD INSTALL on the package source, I get no warnings about the "examples/" subdirectory. So the package installs without problems, but omits the examples. What do I have to do in order to access the files in "examples/"?
At first I misread your question and thought you were the package author. The problem is that as you noticed examples doesn't get copied in when installed. A solution would be for the package authors to put the folder in /inst/examples instead of /examples. Since you don't have control of that we can create a workaround by downloading the source and then using that instead.
# Downloads the source code for a package
# Extracts it to a temporary directory
downloadAndExtract <- function(package, tdir = tempdir()){
down <- download.packages(package, destdir = tdir)
targz <- down[,2]
untar(targz, exdir = tdir)
file.path(tdir, package)
}
path <- downloadAndExtract("XX")
filepath <- file.path(path, "examples", "ex.txt")
dat <- read.table(filepath, header = TRUE, sep = "\t")
Clearly this isn't ideal but since you won't find that file in the installed package we need to resort to some sort of workaround...