-1

I work on a group project. For my analyses, I need a few packages. So in order to let my script work on everyones computer I tell R at the beginning to check for the name of the required package among all installed packages, and, if the name is not there, install it. My code is:

{
ifelse("ggplot2" %in% rownames(installed.packages()),"" ,install.packages("ggplot2"))
ifelse("agricolae" %in% rownames(installed.packages()),"" ,install.packages("agricolae"))
ifelse("lattice" %in% rownames(installed.packages()),"" ,install.packages("lattice"))
ifelse("DescTools" %in% rownames(installed.packages()),"" ,install.packages("DescTools"))
ifelse("FSA" %in% rownames(installed.packages()),"" ,install.packages("FSA")) }

But it seems to work not quite good. Like, R installes the first, but not the second. Is it just because ggplot is too huge and R forgetsthe rest or do I have another mistake?

Thank you all ahead!

Qiyuan
  • 109
  • 10
  • 1- create a vector of package names. 2- create a function. 3- run the function over the vector. e.g.: `x <- c("ggplot2", "lattice") ; f <- function(x) if(!x %in% rownames(installed.packages())) install.packages(x) ; lapply(x, f)` – David Arenburg Feb 27 '19 at 12:28
  • Related: https://stackoverflow.com/questions/54771441/using-ifelse-to-install-a-package – NelsonGon Feb 27 '19 at 13:25

2 Answers2

5

It think the reason you're confused is that you've put all those commands in a braced code block, which will only return 1 thing. If you just removed the braces it might be a little more clear. Observe:

{
    ifelse(TRUE, "yes", "no")
    ifelse(TRUE, "yes", "no")
}
Returns: "yes"

Only one. Even better, try this:

packages=c("ggplot2", "lattice", "simpleCache")

installed = rownames(installed.packages())

for (pkg in packages) {
    if (! pkg %in% installed) {
        install.packages(pkg)
    }
}
nsheff
  • 3,063
  • 2
  • 24
  • 29
  • Well, that is not the reason. Reason is the invisible `NULL` of `install.packages` together with the use of `ifelse` instead of `if`. In the end the OP is anyways not interested in any return value. – thothal Feb 27 '19 at 12:52
1

The problem is that you use ifelse. From the help of ifelse:

‘ifelse’ returns a value with the same shape as ‘test’ which is filled with elements selected from either ‘yes’ or ‘no’ depending on whether the element of ‘test’ is ‘TRUE’ or ‘FALSE’.

Now install.packages returns NULL invisibly and this does not work with ifelse as you can see:

ifelse(T, NULL, 1)
# Error in ans[test & ok] <- rep(yes, length.out = length(ans))[test & ok] : 
# replacement has length zero
# In addition: Warning message:
# In rep(yes, length.out = length(ans)) :
#   'x' is NULL so the result will be NULL

ifelse is intended to be used with vectors for example:

ifelse(c(TRUE, FALSE, TRUE), 1, 2))
# [1] 1 2 1

and does thus not cope well with the NULL value returned by install.packages.

What you want as an one-to-one replacement of your code would be something like:

if ("ggplot2" %in% rownames(installed.packages())) install.packages("ggplot2")

But it is better to use one of the list based answers you got here, because it is much easier to maintain.

thothal
  • 16,690
  • 3
  • 36
  • 71