How to specify (non-R) library path for dynamic library loading in R?
Normally, the iconv
method is picked up from glibc
, which is linked to during build of the R packages in question. For whatever reason, however, iconv
is getting resolved to libiconv
in this case, but it is not linked by the R packages during build.
Original Workaround
One can make the linking to libiconv
explicit by adding the following line to the haven/src/Makevars
source file
PKG_LIBS=-liconv
which then let's you install from source R CMD INSTALL haven
. However, editing packages feels hacky, plus this is something that will need to be done every upgrade, which sounds like a hassle.
Cleaner Workaround
Another option is to use withr::with_makevars
, which allows one to temporarily control Makevars
content. With this technique, one can install directly from the repo:
withr::with_makevars(c(PKG_LIBS="-liconv"), install.packages("haven"), assignment="+=")
Credit: @knb suggested that I inspect the readxl.so
with ldd
and this turned out to be super useful because it showed that the shared object wasn't even trying to link to libiconv. Knowing that, I realized I could manually add the reference via the -liconv
flag. Thanks @knb!
Additional Info
On the package side of things, relevant details about connecting libraries to R packages can be found in the guide for building libraries. On the system configuration side, the R-admin guide has some useful sections.
How do I change the default library path for R packages
See help(Startup)
and help(.libPaths)
as you have several possibilities where this may have gotten set. Among them are
- setting
R_LIBS_USER
- assigning
.libPaths()
in.Rprofile
orRprofile.site
and more.
In this particular case you need to go backwards and unset whereever \\\\The library/path/I/don't/want
is set.
To otherwise ignore it you need to override it use explicitly i.e. via
library("somePackage", lib.loc=.libPaths()[-1])
when loading a package.
Change R default library path using .libPaths in Rprofile.site fails to work
I generally try to keep all of my packages in one library, but if you want to add a library why not append the new library (which must already exist in your filesystem) to the existing library path?
.libPaths( c( .libPaths(), "~/userLibrary") )
# obviously this would need to be a valid file directory in your OS
# min just happened to be on a Mac that day
Or (and this will make the userLibrary the first place to put new packages):
.libPaths( c( "~/userLibrary" , .libPaths() ) )
Then I get (at least back when I wrote this originally):
> .libPaths()
[1] "/Library/Frameworks/R.framework/Versions/2.15/Resources/library"
[2] "/Users/user_name/userLibrary"
The .libPaths
function is a bit different than most other nongraphics functions. It works via side-effect. The functions Sys.getenv
and Sys.setenv
that report and alter the R environment variables have been split apart but .libPaths
can either report or alter its target.
The information about the R startup process can be read at ?Startup
help page and there is RStudio material at: https://support.rstudio.com/hc/en-us/articles/200549016-Customizing-RStudio
In your case it appears that RStudio is not respecting the Rprofile.site settings or perhaps is overriding them by reading an .Rprofile setting from one of the RStudio defaults. It should also be mentioned that the result from this operation also appends the contents of calls to .Library
and .Library.site
, which is further reason why an RStudio- (or any other IDE or network installed-) hosted R might exhibit different behavior.
Since Sys.getenv()
returns the current system environment for the R process, you can see the library and other paths with:
Sys.getenv()[ grep("LIB|PATH", names(Sys.getenv())) ]
The two that matter for storing and accessing packages are (now different on a Linux box):
R_LIBS_SITE /usr/local/lib/R/site-library:/usr/lib/R/site-library:/usr/lib/R/library
R_LIBS_USER /home/david/R/x86_64-pc-linux-gnu-library/3.5.1/
how to set lib-paths in R to have a single directory which is C:\Users\Username\Documents\...
Hong Ooi's answer: "You can't, and you don't want to, remove the base library location. That's where R's own packages live, and without them you can't use R."
Setting a directory path to a dynamically linked library in an R package
The standard way to do this, as described in Writing R Extensions, is:
1.5.4 useDynLib
A
NAMESPACE
file can contain one or moreuseDynLib
directives which allows shared objects that need to be loaded.* The directive
useDynLib(foo)
registers the shared object
foo
** for loading withlibrary.dynam
. Loading of registered object(s) occurs after the package code has been loaded and before running the load hook function. Packages that would only need a load hook function to load a shared object can use theuseDynLib
directive instead.
*
NB: this will only be read in all versions of R if the package contains R code in a R directory.**
Note that this is the basename of the shared object, and the appropriate extension (.so or .dll) will be added.
Setting LD_LIBRARY_PATH from inside R
With help from Hans Lub, the way to solve the problem is by using the dyn.load()
function and supplying the full path to the library:
dyn.load('path_to_library')
and then, loading via library
should work.
Related Topics
How to Get Rstudio to Automatically Compile R Markdown Vignettes
How to Identify the Distribution of the Given Data Using R
Install a Local R Package with Dependencies from Cran Mirror
How to Make Object Created Within Function Usable Outside
Predicting Lda Topics for New Data
Kruskal-Wallis Test with Details on Pairwise Comparisons
Remove Spacing Around Plotting Area in R
Differences in Heatmap/Clustering Defaults in R (Heatplot Versus Heatmap.2)
Piecewise Regression with R: Plotting the Segments
Adding Custom Image to Geom_Polygon Fill in Ggplot
How to Save a Data Frame as CSV to a User Selected Location Using Tcltk
Avoid Rbind()/Cbind() Conversion from Numeric to Factor
What Is a Fast Way to Set Debugging Code at a Given Line in a Function