R/init_env.R

Defines functions init_env

Documented in init_env

#' @title Initialize Environment for 'python' Backend
#' @description
#' Initializes the 'python' backend required for the functionality of lionfish.
#' At first it searches whether a 'python' environment with the provided name
#' exists or not. If it does, it will be loaded and the 'python' function
#' 'check_backend' is run to check if it works properly. If no 'python'
#' environment with the provided name exists, it will be installed and then
#' loaded. This can either be done with or without Anaconda as package manager.
#' Anaconda can be more robust, but the GUI will appear dated. Thus, trying
#' 'init_env' with virtual_env = "virtual_env" out first is recommended.
#' For 'Windows' users, the path to the tk and tcl libraries will be set,
#' otherwise tkinter cannot run.
#'
#' @param env_name a string that defines the name of the python environment reticulate uses.
#' This can be useful if one wants to use a preinstalled python environment.
#' @param virtual_env either "virtual_env" or "anaconda". "virtual_env" creates
#' a virtual environment, which has the advantage that the GUI looks much nicer
#' and no previous python installation is required,but the setup of the
#' environment can be more error prone. "anaconda" installs the python
#' environment via Anaconda, which can be more stable, but the GUI looks more
#' dated.
#'
#' @param local logical
#'
#' @export
#'
#' @return initializes python environment
#'
#' @examples
#' if (check_venv()){
#' init_env(env_name = "r-lionfish", virtual_env = "virtual_env")
#' } else if (check_conda_env()){
#' init_env(env_name = "r-lionfish", virtual_env = "anaconda")
#' }
init_env <- function(env_name = "r-lionfish", virtual_env = "virtual_env", local = FALSE) {
  # Check if python is available
  reticulate::py_available(initialize = FALSE)

  required_packages <- c(
    "pandas", "numpy>=2.0", "matplotlib",
    "customtkinter", "statsmodels", "seaborn"
  )

  if (virtual_env == "anaconda") {
    # check if python environment exists and create new one if not
    if (env_name %in% reticulate::conda_list()$name == FALSE) {
      reticulate::conda_create(env_name)
    }
    # initialize python environment
    reticulate::use_condaenv(env_name)

    # check if required packages are installed and install them if not
    package_names <- reticulate::py_list_packages(envname = env_name, "conda")
    for (package in required_packages) {
      if (package %in% package_names$package == FALSE) {
        if (package == "customtkinter") {
          reticulate::conda_install(env_name, package, pip = TRUE)
        } else {
          reticulate::conda_install(env_name, package)
        }
      }
    }
  } else if (virtual_env == "virtual_env") {
    if (env_name %in% reticulate::virtualenv_list() == FALSE) {
      py_version <- unlist(reticulate::virtualenv_starter(all = TRUE)$version[1])
      py_version <- paste(py_version, collapse = ".")
      reticulate::install_python(version = py_version)
      reticulate::virtualenv_create(env_name)
    }
    # initialize python environment
    reticulate::use_virtualenv(env_name)

    # check if required packages are installed and install them if not
    package_names <- reticulate::py_list_packages(envname = env_name, "virtualenv")
    for (package in required_packages) {
      if (package %in% package_names$package == FALSE) {
        if (package == "customtkinter") {
          reticulate::virtualenv_install(env_name, package)
        } else {
          reticulate::virtualenv_install(env_name, package)
        }
      }
    }
  }

  base::message(base::sprintf('Python environment "%s" successfully loaded', env_name), "\n")

  # Check accessibility of python functions
  lionfish_dir <- find.package("lionfish", lib.loc = NULL, quiet = TRUE)

  if (dir.exists(file.path(lionfish_dir, "/inst"))) {
    check_dir <- base::paste(lionfish_dir, "/inst/python/check_backend.py", sep = "")
  } else {
    check_dir <- base::paste(lionfish_dir, "/python/check_backend.py", sep = "")
  }
  reticulate::source_python(check_dir)
  reticulate::py$check_backend()

  # set directory of tcl/tk installation for windows users
  if (.Platform$OS.type == "windows") {
    home_dir <- gsub("\\\\", "/", Sys.getenv("USERPROFILE"))

    sys <- reticulate::import("sys")
    full_python_version <- sys$version
    py_version <- strsplit(full_python_version, " ")[[1]][1]

    py_dir <- "/AppData/Local/r-reticulate/r-reticulate/pyenv/pyenv-win/versions/"
    tk <- "/tk/tk8.6"
    tcl <- "/tcl/tcl8.6"

    tcl_dir <- base::paste0(home_dir, py_dir, py_version, tcl)
    tk_dir <- base::paste0(home_dir, py_dir, py_version, tk)

    Sys.setenv(TCL_LIBRARY = tcl_dir)
    Sys.setenv(TK_LIBRARY = tk_dir)

    cat("tcl directory", tcl_dir, "\n")
    cat("tk directory", tk_dir, "\n")
  }
}

Try the lionfish package in your browser

Any scripts or data that you put into this service are public.

lionfish documentation built on April 4, 2025, 2:19 a.m.