gusevlab / fusion_twas

methods for functional summary-based imputation
http://gusevlab.org/projects/fusion/
GNU General Public License v3.0
75 stars 45 forks source link

Move away from plink2R? #13

Open lcolladotor opened 5 years ago

lcolladotor commented 5 years ago

Hi,

I ran into the same plink2R installation issue as @jluyapan did at https://github.com/gabraham/plink2R/issues/6#issuecomment-489359462 using R 3.6.1. While this issue could be solved by updating the package a little bit, it seems from https://github.com/gabraham/plink2R/issues/7#issuecomment-443550858 that the plink2R project has been abandoned (@anadon also wanted to use it for FUSION TWAS). The author of plink2R (@gabraham) recommends switching to BEDMatrix at https://cran.r-project.org/web/packages/BEDMatrix/index.html by @agrueneberg.

From https://github.com/gusevlab/fusion_twas/search?q=plink2R&unscoped_q=plink2R I know that you use plink2R in three scripts. From https://github.com/gusevlab/fusion_twas/blob/0ab190e740f4631bb137bd48e5a54ccb2ddda7c9/FUSION.compute_weights.R I can see that you read BED files using impute = 'avg' and use all 3 components returned by plink2R::read_plink().

Can BEDMatrix be used?

I asked myself if BEDMatrix could be used to replace plink2R for FUSION TWAS and it looks like it can, mostly as shown below using R 3.5.3 (where plink2R can be installed without issues).

library('BEDMatrix')
path <- system.file("extdata", "example.bed", 
    package = "BEDMatrix")
m <- BEDMatrix(path)

library('plink2R')
genos <- read_plink(gsub('\\.bed', '', path), impute = 'avg')
lapply(genos, head)

identical(
    ncol(m),
    nrow(genos$bim)
)
identical(
    gsub('_.*', '', colnames(m)),
    genos$bim[, 2]
)

sum(is.na(m2))
sum(is.na(genos$bed))
table(as.vector(m2 - genos$bed), useNA = 'ifany')

## Impute using the average
## equivalent to 
## https://github.com/gabraham/plink2R/blob/master/plink2R/src/data.cpp#L153-L192
means <- colMeans(m2, na.rm = TRUE)
m3 <- m2
m3[is.na(m2)] <- rep(means, colSums(is.na(m2)))

## Force the names to be the same
## Could also use the bim and fam objects as in
## https://github.com/gabraham/plink2R/blob/master/plink2R/R/plink2R.R#L20-L21
## to avoid any regex issues
colnames(m3) <- gsub('_.*', '', colnames(m3))
rownames(m3) <- gsub('_', ':', rownames(m3))
identical(
    m3,
    genos$bed
)

## BEDMatrix doesn't read the full fam file as you can see at
## https://github.com/QuantGen/BEDMatrix/blob/master/R/BEDMatrix.R#L30-L61

## plink2R does (although with the slower utils::read.table function)
## https://github.com/gabraham/plink2R/blob/master/plink2R/R/plink2R.R#L17
famfile <- gsub('\\.bed', '\\.fam', path)
fam <- read.table(famfile, header=FALSE, sep="", stringsAsFactors=FALSE)

## For https://github.com/gusevlab/fusion_twas/blob/0ab190e740f4631bb137bd48e5a54ccb2ddda7c9/FUSION.compute_weights.R#L256
identical(
    fam[, c(1,2,6)],
    genos$fam[, c(1,2,6)]
)

## BEDMatrix doesn't read the full bim file as you can see at
## https://github.com/QuantGen/BEDMatrix/blob/master/R/BEDMatrix.R#L75-L108

## plink2R does (although with the slower utils::read.table function)
## https://github.com/gabraham/plink2R/blob/master/plink2R/R/plink2R.R#L16
bimfile <- gsub('\\.bed', '\\.bim', path)
bim <- read.table(bimfile, header=FALSE, sep="", stringsAsFactors=FALSE)
## For https://github.com/gusevlab/fusion_twas/blob/0ab190e740f4631bb137bd48e5a54ccb2ddda7c9/FUSION.compute_weights.R#L374
identical(
    bim,
    genos$bim
)

Initial BEDMatrix dependent function

I wrote a read_plink_custom function that used BEDMatrix to read in the genotype matrix and that can handle the impute ='avg scenario from plink2R. I didn't implement the impute = 'random' scenario since I don't think that you use it (from https://github.com/gabraham/plink2R/blob/master/plink2R/src/data.cpp#L194-L255).

read_plink_custom <- function(root, impute = c('none', 'avg', 'random')) {
    if(impute == 'random') {
        stop("The 'impute' random option has not been implemented.", call. = FALSE)
    }

    ## structure from https://github.com/gabraham/plink2R/blob/master/plink2R/R/plink2R.R
    proot <- path.expand(root)

    bedfile <- paste(proot, ".bed", sep="")
    famfile <- paste(proot, ".fam", sep="")
    bimfile <- paste(proot, ".bim", sep="")

    ## Could change this code to use data.table
    bim <- read.table(bimfile, header=FALSE, sep="", stringsAsFactors=FALSE)
    fam <- read.table(famfile, header=FALSE, sep="", stringsAsFactors=FALSE)
    ## Set the dimensions
    geno <- BEDMatrix::BEDMatrix(bedfile, n = nrow(fam), p = nrow(bim))

    ## Convert to a matrix
    geno <- as.matrix(geno)
    if(impute == 'avg') {
        ## Check if any are missing
        geno_na <- is.na(geno)
        if(any(geno_na)) {
            means <- colMeans(geno, na.rm = TRUE)
            geno[geno_na] <- rep(means, colSums(geno_na))
        }
    }
    colnames(geno) <- bim[,2]
    rownames(geno) <- paste(fam[,1], fam[, 2], sep=":")

    list(bed=geno, fam=fam, bim=bim)    
}

genos_custom <- read_plink_custom(gsub('\\.bed', '', path), impute = 'avg')
identical(
    genos_custom,
    genos
)

data.table flavor

I then wrote a version of the above function that uses data.table which in theory should be faster.

read_plink_custom_fast <- function(root, impute = c('none', 'avg', 'random')) {
    if(impute == 'random') {
        stop("The 'impute' random option has not been implemented.", call. = FALSE)
    }
    if(!requireNamespace("data.table", quietly = TRUE)) {
        stop("Please install the 'data.table' package using install.packages('data.table').", call. = FALSE)
    }

    ## structure from https://github.com/gabraham/plink2R/blob/master/plink2R/R/plink2R.R
    proot <- path.expand(root)

    bedfile <- paste(proot, ".bed", sep="")
    famfile <- paste(proot, ".fam", sep="")
    bimfile <- paste(proot, ".bim", sep="")

    ## Could change this code to use data.table
    bim <- data.table::fread(
        bimfile,
        colClasses = list('character' = c(2, 5, 6), 'integer' = c(1, 3, 4)),
        showProgress = FALSE,
        data.table = FALSE
    )
    fam <- data.table::fread(famfile,
        colClasses = list('character' = 1:2, 'integer' = 3:6),
        showProgress = FALSE,
        data.table = FALSE
    )
    ## Set the dimensions
    geno <- BEDMatrix::BEDMatrix(bedfile, n = nrow(fam), p = nrow(bim))

    ## Convert to a matrix
    geno <- as.matrix(geno)
    if(impute == 'avg') {
        ## Check if any are missing
        geno_na <- is.na(geno)
        if(any(geno_na)) {
            means <- colMeans(geno, na.rm = TRUE)
            geno[geno_na] <- rep(means, colSums(geno_na))
        }
    }
    ## Extract data using the data.table syntax
    ## in case fread(data.table = TRUE) was used (which is the default)
    # colnames(geno) <- bim[[2]]
    # rownames(geno) <- paste(fam[[1]], fam[[2]], sep=":")
    colnames(geno) <- bim[,2]
    rownames(geno) <- paste(fam[,1], fam[, 2], sep=":")

    ## If you used fread(data.table = TRUE) then you need to cast
    ## the objects using as.data.frame()
    list(bed=geno, fam=fam, bim=bim)
}

genos_custom_fast <- read_plink_custom_fast(gsub('\\.bed', '', path), impute = 'avg')
identical(
    genos_custom_fast,
    genos
)

However, the microbenchmark results show that that's not the case. At least with the BEDMatrix example BED file, though it could play a role in much larger BED files.

library('microbenchmark')
micro <- microbenchmark(
    read_plink_custom(gsub('\\.bed', '', path), impute = 'avg'),
    read_plink_custom_fast(gsub('\\.bed', '', path), impute = 'avg')
)
options(width = 150)
summary(micro)
#                                                                 expr      min        lq     mean    median        uq      max neval cld
# 1      read_plink_custom(gsub("\\\\.bed", "", path), impute = "avg") 6.009474  6.538338  7.91712  7.738728  8.242563 15.08098   100  a
# 2 read_plink_custom_fast(gsub("\\\\.bed", "", path), impute = "avg") 9.096066 10.006155 10.94152 10.580656 11.017670 17.00687   100   b

In any case both functions work. So yes, BEDMatrix can be used to read in BED files with either the 'impute' = 'none' or 'impute' = 'avg' methods from plink2R.

## Check the 'none' scenario
genos_none <- read_plink(gsub('\\.bed', '', path), impute = 'none')
genos_custom_none <- read_plink_custom(gsub('\\.bed', '', path), impute = 'none')
genos_custom_fast_none <- read_plink_custom_fast(gsub('\\.bed', '', path), impute = 'none')
testthat::expect_equivalent(
    genos_custom_none,
    genos_none
)
testthat::expect_equivalent(
    genos_custom_fast_none,
    genos_none
)

Moving forward

Moving forward, I guess that it would be ideal if BEDMatrix incorporated a version of the read_plink_custom()/read_plink_custom_fast() function such that you would only need to change library('plink2R') to library('BEDMatrix') in your scripts and to enable others to keep using what plink2R provided in a package that is maintained and available from CRAN. The only part missing would be the 'impute' = 'random' part of https://github.com/gabraham/plink2R/blob/master/plink2R/src/data.cpp#L194-L255 though I don't know what drand48() returns (I imagine that it could be replaced with some R code). This is likely better than creating another GitHub R package with this function, as it could likely end up being in "abandonware" mode as plink2R did.

Let me know what you think.

Best, Leo

Reproducibility

library('sessioninfo')
session_info()
# ─ Session info ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
#  setting  value
#  version  R version 3.5.3 Patched (2019-03-11 r76311)
#  os       Red Hat Enterprise Linux Server release 6.9 (Santiago)
#  system   x86_64, linux-gnu
#  ui       X11
#  language (EN)
#  collate  en_US.UTF-8
#  ctype    en_US.UTF-8
#  tz       US/Eastern
#  date     2019-08-22
#
# ─ Packages ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
#  package        * version   date       lib source
#  assertthat       0.2.1     2019-03-21 [2] CRAN (R 3.5.1)
#  BEDMatrix      * 1.6.1     2019-06-21 [1] CRAN (R 3.5.3)
#  cli              1.1.0     2019-03-19 [1] CRAN (R 3.5.3)
#  codetools        0.2-16    2018-12-24 [3] CRAN (R 3.5.3)
#  colorout       * 1.2-0     2018-05-02 [1] Github (jalvesaq/colorout@c42088d)
#  colorspace       1.4-1     2019-03-18 [2] CRAN (R 3.5.1)
#  crayon           1.3.4     2017-09-16 [1] CRAN (R 3.5.0)
#  crochet          2.2.0     2019-06-13 [1] CRAN (R 3.5.3)
#  data.table       1.12.2    2019-04-07 [1] CRAN (R 3.5.3)
#  digest           0.6.20    2019-07-04 [1] CRAN (R 3.5.3)
#  dplyr            0.8.3     2019-07-04 [1] CRAN (R 3.5.3)
#  ggplot2          3.2.1     2019-08-10 [1] CRAN (R 3.5.3)
#  glue             1.3.1     2019-03-12 [1] CRAN (R 3.5.1)
#  gtable           0.3.0     2019-03-25 [2] CRAN (R 3.5.1)
#  htmltools        0.3.6     2017-04-28 [2] CRAN (R 3.5.0)
#  htmlwidgets      1.3       2018-09-30 [1] CRAN (R 3.5.1)
#  httpuv           1.5.1     2019-04-05 [2] CRAN (R 3.5.3)
#  jsonlite         1.6       2018-12-07 [2] CRAN (R 3.5.1)
#  later            0.8.0     2019-02-11 [2] CRAN (R 3.5.1)
#  lattice          0.20-38   2018-11-04 [3] CRAN (R 3.5.3)
#  lazyeval         0.2.2     2019-03-15 [2] CRAN (R 3.5.1)
#  magrittr         1.5       2014-11-22 [1] CRAN (R 3.5.0)
#  MASS             7.3-51.1  2018-11-01 [3] CRAN (R 3.5.3)
#  Matrix           1.2-15    2018-11-01 [3] CRAN (R 3.5.3)
#  microbenchmark * 1.4-6     2018-10-18 [1] CRAN (R 3.5.3)
#  multcomp         1.4-10    2019-03-05 [2] CRAN (R 3.5.1)
#  munsell          0.5.0     2018-06-12 [2] CRAN (R 3.5.1)
#  mvtnorm          1.0-11    2019-06-19 [2] CRAN (R 3.5.3)
#  pillar           1.4.2     2019-06-29 [1] CRAN (R 3.5.3)
#  pkgconfig        2.0.2     2018-08-16 [1] CRAN (R 3.5.1)
#  plink2R        * 1.1       2018-12-06 [1] Github (gabraham/plink2R@d74be01)
#  png              0.1-7     2013-12-03 [2] CRAN (R 3.5.0)
#  promises         1.0.1     2018-04-13 [2] CRAN (R 3.5.0)
#  purrr            0.3.2     2019-03-15 [2] CRAN (R 3.5.1)
#  R6               2.4.0     2019-02-14 [2] CRAN (R 3.5.1)
#  Rcpp           * 1.0.2     2019-07-25 [1] CRAN (R 3.5.3)
#  RcppEigen      * 0.3.3.5.0 2018-11-24 [1] CRAN (R 3.5.1)
#  rlang            0.4.0     2019-06-25 [1] CRAN (R 3.5.3)
#  rmote          * 0.3.4     2018-05-02 [1] deltarho (R 3.5.0)
#  sandwich         2.5-1     2019-04-06 [2] CRAN (R 3.5.3)
#  scales           1.0.0     2018-08-09 [2] CRAN (R 3.5.1)
#  servr            0.15      2019-08-07 [1] CRAN (R 3.5.3)
#  sessioninfo    * 1.1.1     2018-11-05 [1] CRAN (R 3.5.1)
#  survival         2.43-3    2018-11-26 [3] CRAN (R 3.5.3)
#  testthat         2.2.1     2019-07-25 [1] CRAN (R 3.5.3)
#  TH.data          1.0-10    2019-01-21 [2] CRAN (R 3.5.1)
#  tibble           2.1.3     2019-06-06 [1] CRAN (R 3.5.3)
#  tidyselect       0.2.5     2018-10-11 [2] CRAN (R 3.5.1)
#  withr            2.1.2     2018-03-15 [2] CRAN (R 3.5.0)
#  xfun             0.9       2019-08-21 [1] CRAN (R 3.5.3)
#  zoo              1.8-6     2019-05-28 [2] CRAN (R 3.5.3)
#
# [1] /users/lcollado/R/x86_64-pc-linux-gnu-library/3.5.x
# [2] /jhpce/shared/jhpce/core/conda/miniconda-3/envs/svnR-3.5.x/R/3.5.x/lib64/R/site-library
# [3] /jhpce/shared/jhpce/core/conda/miniconda-3/envs/svnR-3.5.x/R/3.5.x/lib64/R/library

system('plink --version')
# PLINK v1.90b6.6 64-bit (10 Oct 2018)
carbocation commented 5 years ago

In the interim, I've created a branch that trivially strips out the offending lines from the package description so plink2R can be installed on R 3.6.1.

It can be installed as so: devtools::install_github("carbocation/plink2R/plink2R", ref="carbocation-permit-r361")

(PR is submitted to the main package: https://github.com/gabraham/plink2R/pull/8#issue-312337301 )

lcolladotor commented 5 years ago

Nice, thanks @carbocation!

rodrigoduarte88 commented 2 years ago

As of today, I was able to install plink2R using the following environment for fusion:

conda env create --file fusion_final_environment.yml

The fusion_final_environment.yml file contains:

name: fusion_final
channels:
  - bioconda
  - r
  - conda-forge
  - defaults
dependencies:
  - _libgcc_mutex=0.1=conda_forge
  - _openmp_mutex=4.5=1_gnu
  - _r-mutex=1.0.1=anacondar_1
  - argon2-cffi=20.1.0=py36h8f6f2f9_2
  - async_generator=1.10=py_0
  - attrs=21.2.0=pyhd8ed1ab_0
  - backports=1.0=py_2
  - backports.functools_lru_cache=1.6.4=pyhd8ed1ab_0
  - binutils_impl_linux-64=2.35.1=h193b22a_2
  - binutils_linux-64=2.35=h67ddf6f_30
  - bleach=1.4.2=py36_0
  - bwidget=1.9.14=ha770c72_0
  - bzip2=1.0.8=h7f98852_4
  - c-ares=1.17.1=h7f98852_1
  - ca-certificates=2021.5.30=ha878542_0
  - cairo=1.16.0=h6cf1ce9_1008
  - certifi=2021.5.30=py36h5fab9bb_0
  - cffi=1.14.5=py36hc120d54_0
  - curl=7.77.0=hea6ffbf_0
  - decorator=5.0.9=pyhd8ed1ab_0
  - defusedxml=0.7.1=pyhd8ed1ab_0
  - entrypoints=0.3=pyhd8ed1ab_1003
  - font-ttf-dejavu-sans-mono=2.37=hab24e00_0
  - font-ttf-inconsolata=3.000=h77eed37_0
  - font-ttf-source-code-pro=2.038=h77eed37_0
  - font-ttf-ubuntu=0.83=hab24e00_0
  - fontconfig=2.13.1=hba837de_1005
  - fonts-conda-ecosystem=1=0
  - fonts-conda-forge=1=0
  - freetype=2.10.4=h0708190_1
  - fribidi=1.0.10=h36c2ea0_0
  - gcc_impl_linux-64=9.3.0=h70c0ae5_19
  - gcc_linux-64=9.3.0=hf25ea35_30
  - gettext=0.19.8.1=h0b5b191_1005
  - gfortran_impl_linux-64=9.3.0=hc4a2995_19
  - gfortran_linux-64=9.3.0=hdc58fab_30
  - graphite2=1.3.13=h58526e2_1001
  - gsl=2.6=he838d99_2
  - gxx_impl_linux-64=9.3.0=hd87eabc_19
  - gxx_linux-64=9.3.0=h3fbe746_30
  - harfbuzz=2.8.1=h83ec7ef_0
  - html5lib=1.1=pyh9f0ad1d_0
  - icu=68.1=h58526e2_0
  - importlib-metadata=4.4.0=py36h5fab9bb_0
  - ipykernel=5.5.5=py36hcb3619a_0
  - ipython=5.8.0=py36_1
  - ipython_genutils=0.2.0=py_1
  - jbig=2.1=h7f98852_2003
  - jinja2=3.0.1=pyhd8ed1ab_0
  - jpeg=9d=h36c2ea0_0
  - jsonschema=3.2.0=pyhd8ed1ab_3
  - jupyter_client=6.1.12=pyhd8ed1ab_0
  - jupyter_core=4.7.1=py36h5fab9bb_0
  - jupyterlab_pygments=0.1.2=pyh9f0ad1d_0
  - kernel-headers_linux-64=2.6.32=h77966d4_13
  - krb5=1.19.1=hcc1bbae_0
  - ld_impl_linux-64=2.35.1=hea4e1c9_2
  - lerc=2.2.1=h9c3ff4c_0
  - libblas=3.9.0=9_openblas
  - libcblas=3.9.0=9_openblas
  - libcurl=7.77.0=h2574ce0_0
  - libdeflate=1.7=h7f98852_5
  - libedit=3.1.20191231=he28a2e2_2
  - libev=4.33=h516909a_1
  - libffi=3.3=h58526e2_2
  - libgcc-devel_linux-64=9.3.0=h7864c58_19
  - libgcc-ng=9.3.0=h2828fa1_19
  - libgfortran-ng=9.3.0=hff62375_19
  - libgfortran5=9.3.0=hff62375_19
  - libglib=2.68.2=h3e27bee_2
  - libgomp=9.3.0=h2828fa1_19
  - libiconv=1.16=h516909a_0
  - liblapack=3.9.0=9_openblas
  - libnghttp2=1.43.0=h812cca2_0
  - libopenblas=0.3.15=pthreads_h8fe5266_1
  - libpng=1.6.37=h21135ba_2
  - libsodium=1.0.18=h36c2ea0_1
  - libssh2=1.9.0=ha56f1ee_6
  - libstdcxx-devel_linux-64=9.3.0=hb016644_19
  - libstdcxx-ng=9.3.0=h6de172a_19
  - libtiff=4.3.0=hf544144_1
  - libuuid=2.32.1=h7f98852_1000
  - libwebp-base=1.2.0=h7f98852_2
  - libxcb=1.13=h7f98852_1003
  - libxml2=2.9.12=h72842e0_0
  - lz4-c=1.9.3=h9c3ff4c_0
  - make=4.3=hd18ef5c_1
  - markupsafe=2.0.1=py36h8f6f2f9_0
  - mistune=0.8.4=py36h8f6f2f9_1003
  - nbclient=0.5.3=pyhd8ed1ab_0
  - nbconvert=6.0.7=py36h5fab9bb_3
  - nbformat=5.1.3=pyhd8ed1ab_0
  - ncurses=6.2=h58526e2_4
  - nest-asyncio=1.5.1=pyhd8ed1ab_0
  - notebook=6.3.0=py36h5fab9bb_0
  - openblas=0.3.15=pthreads_h4748800_1
  - openssl=1.1.1k=h7f98852_0
  - pandoc=2.14.0.1=h7f98852_0
  - pandocfilters=1.4.2=py_1
  - pango=1.48.5=hb8ff022_0
  - pcre=8.44=he1b5a44_0
  - pexpect=4.8.0=pyh9f0ad1d_2
  - pickleshare=0.7.5=py_1003
  - pip=21.1.2=pyhd8ed1ab_0
  - pixman=0.40.0=h36c2ea0_0
  - prometheus_client=0.11.0=pyhd8ed1ab_0
  - prompt_toolkit=1.0.15=py_1
  - pthread-stubs=0.4=h36c2ea0_1001
  - ptyprocess=0.7.0=pyhd3deb0d_0
  - pycparser=2.20=pyh9f0ad1d_2
  - pygments=2.9.0=pyhd8ed1ab_0
  - pyrsistent=0.17.3=py36h8f6f2f9_2
  - python=3.6.13=hffdb5ce_0_cpython
  - python-dateutil=2.8.1=py_0
  - python_abi=3.6=1_cp36m
  - pyzmq=22.1.0=py36h7068817_0
  - r-askpass=1.1=r36hcfec24a_2
  - r-assertthat=0.2.1=r36h6115d3f_2
  - r-backports=1.2.1=r36hcfec24a_0
  - r-base=3.6.3=hbcea092_8
  - r-base64enc=0.1_3=r36hcfec24a_1004
  - r-blob=1.2.1=r36h6115d3f_1
  - r-boot=1.3_28=r36hc72bb7e_0
  - r-brio=1.1.2=r36hcfec24a_0
  - r-broom=0.7.6=r36hc72bb7e_0
  - r-bslib=0.2.5.1=r36hc72bb7e_0
  - r-cachem=1.0.5=r36hcfec24a_0
  - r-callr=3.7.0=r36hc72bb7e_0
  - r-caret=6.0_88=r36hcfec24a_0
  - r-cellranger=1.1.0=r36h6115d3f_1003
  - r-class=7.3_19=r36hcfec24a_0
  - r-cli=2.5.0=r36hc72bb7e_0
  - r-clipr=0.7.1=r36h142f84f_0
  - r-cluster=2.1.2=r36h859d828_0
  - r-codetools=0.2_18=r36hc72bb7e_0
  - r-colorspace=2.0_1=r36hcfec24a_0
  - r-commonmark=1.7=r36hcfec24a_1002
  - r-cpp11=0.2.7=r36hc72bb7e_0
  - r-crayon=1.4.1=r36hc72bb7e_0
  - r-curl=4.3.1=r36hcfec24a_0
  - r-data.table=1.14.0=r36hcfec24a_0
  - r-dbi=1.1.1=r36hc72bb7e_0
  - r-dbplyr=2.1.1=r36hc72bb7e_0
  - r-desc=1.3.0=r36hc72bb7e_0
  - r-diffobj=0.3.4=r36hcfec24a_0
  - r-digest=0.6.27=r36h03ef668_0
  - r-dplyr=1.0.6=r36h03ef668_1
  - r-dtplyr=1.1.0=r36hc72bb7e_0
  - r-ellipsis=0.3.2=r36hcfec24a_0
  - r-essentials=3.6.0=r36_0
  - r-evaluate=0.14=r36h6115d3f_2
  - r-fansi=0.4.0=r36h96ca727_0
  - r-farver=2.1.0=r36h03ef668_0
  - r-fastmap=1.1.0=r36h03ef668_0
  - r-forcats=0.5.1=r36hc72bb7e_0
  - r-foreach=1.5.1=r36h142f84f_0
  - r-foreign=0.8_71=r36h96ca727_0
  - r-formatr=1.6=r36h6115d3f_0
  - r-fs=1.5.0=r36h0357c0b_0
  - r-gargle=1.1.0=r36hc72bb7e_0
  - r-generics=0.1.0=r36hc72bb7e_0
  - r-ggplot2=3.3.3=r36hc72bb7e_0
  - r-glmnet=4.1_1=r36h859d828_0
  - r-glue=1.4.2=r36hcfec24a_0
  - r-googledrive=1.0.1=r36h6115d3f_1
  - r-googlesheets4=0.3.0=r36hc72bb7e_0
  - r-gower=0.2.2=r36hcdcec82_0
  - r-gtable=0.3.0=r36h6115d3f_3
  - r-haven=2.4.1=r36h2713e49_0
  - r-hexbin=1.28.2=r36h859d828_0
  - r-highr=0.9=r36hc72bb7e_0
  - r-hms=1.1.0=r36hc72bb7e_0
  - r-htmltools=0.5.1.1=r36h03ef668_0
  - r-htmlwidgets=1.5.3=r36hc72bb7e_0
  - r-httpuv=1.6.1=r36h03ef668_0
  - r-httr=1.4.2=r36h6115d3f_0
  - r-ids=1.0.1=r36h6115d3f_1
  - r-ipred=0.9_11=r36hcfec24a_0
  - r-irdisplay=1.0=r36hd8ed1ab_0
  - r-irkernel=1.2=r36hc72bb7e_0
  - r-isoband=0.2.4=r36h03ef668_0
  - r-iterators=1.0.13=r36h142f84f_0
  - r-jquerylib=0.1.4=r36hc72bb7e_0
  - r-jsonlite=1.7.2=r36hcfec24a_0
  - r-kernsmooth=2.23_20=r36h742201e_0
  - r-knitr=1.33=r36hc72bb7e_0
  - r-labeling=0.4.2=r36h142f84f_0
  - r-later=1.2.0=r36h03ef668_0
  - r-lattice=0.20_44=r36hcfec24a_0
  - r-lava=1.6.9=r36hc72bb7e_0
  - r-lifecycle=1.0.0=r36hc72bb7e_0
  - r-lubridate=1.7.10=r36h03ef668_0
  - r-magrittr=2.0.1=r36hcfec24a_1
  - r-maps=3.3.0=r36hcdcec82_1004
  - r-markdown=1.1=r36hcfec24a_1
  - r-mass=7.3_54=r36hcfec24a_0
  - r-matrix=1.2_17=r36h96ca727_0
  - r-mgcv=1.8_28=r36h96ca727_0
  - r-mime=0.10=r36hcfec24a_0
  - r-modelmetrics=1.2.2.2=r36h0357c0b_1
  - r-modelr=0.1.8=r36h6115d3f_0
  - r-munsell=0.5.0=r36h6115d3f_1003
  - r-nlme=3.1_152=r36h859d828_0
  - r-nnet=7.3_16=r36hcfec24a_0
  - r-numderiv=2016.8_1.1=r36h6115d3f_3
  - r-openssl=1.4.4=r36he36bf35_0
  - r-pbdzmq=0.3_5=r36h42bf92c_1
  - r-pillar=1.6.1=r36hc72bb7e_0
  - r-pkgconfig=2.0.3=r36h6115d3f_1
  - r-pkgload=1.2.1=r36h03ef668_0
  - r-plyr=1.8.6=r36h0357c0b_1
  - r-praise=1.0.0=r36h6115d3f_1004
  - r-prettyunits=1.1.1=r36h6115d3f_1
  - r-proc=1.17.0.1=r36h03ef668_0
  - r-processx=3.5.2=r36hcfec24a_0
  - r-prodlim=2019.11.13=r36h0357c0b_1
  - r-progress=1.2.2=r36h6115d3f_2
  - r-promises=1.2.0.1=r36h03ef668_0
  - r-ps=1.6.0=r36hcfec24a_0
  - r-purrr=0.3.4=r36hcfec24a_1
  - r-quantmod=0.4.18=r36hc72bb7e_0
  - r-r6=2.5.0=r36hc72bb7e_0
  - r-randomforest=4.6_14=r36h580db52_1004
  - r-rappdirs=0.3.3=r36hcfec24a_0
  - r-rbokeh=0.6.3=r36_0
  - r-rcolorbrewer=1.1_2=r36h6115d3f_1003
  - r-rcpp=1.0.6=r36h03ef668_0
  - r-rcppeigen=0.3.3.5.0=r36h29659fb_0
  - r-readr=1.4.0=r36h1b71b39_0
  - r-readxl=1.3.1=r36hde08347_4
  - r-recipes=0.1.16=r36hc72bb7e_0
  - r-recommended=3.6.0=r36_0
  - r-rematch=1.0.1=r36h6115d3f_1003
  - r-rematch2=2.1.2=r36h6115d3f_1
  - r-repr=1.1.3=r36h785f33e_0
  - r-reprex=2.0.0=r36hc72bb7e_0
  - r-reshape2=1.4.4=r36h0357c0b_1
  - r-rlang=0.4.11=r36hcfec24a_0
  - r-rmarkdown=2.8=r36hc72bb7e_0
  - r-rpart=4.1_15=r36hcfec24a_2
  - r-rprojroot=2.0.2=r36hc72bb7e_0
  - r-rstudioapi=0.13=r36hc72bb7e_0
  - r-rvest=1.0.0=r36hc72bb7e_0
  - r-sass=0.4.0=r36h03ef668_0
  - r-scales=1.1.1=r36h6115d3f_0
  - r-selectr=0.4_2=r36h6115d3f_1
  - r-shape=1.4.6=r36ha770c72_0
  - r-shiny=1.6.0=r36hc72bb7e_0
  - r-sourcetools=0.1.7=r36he1b5a44_1002
  - r-spatial=7.3_14=r36hcfec24a_0
  - r-squarem=2021.1=r36hc72bb7e_0
  - r-stringi=1.6.2=r36hcabe038_0
  - r-stringr=1.4.0=r36h6115d3f_2
  - r-survival=3.2_11=r36hcfec24a_0
  - r-sys=3.4=r36hcfec24a_0
  - r-testthat=3.0.2=r36h03ef668_0
  - r-tibble=3.1.2=r36hcfec24a_0
  - r-tidyr=1.1.3=r36h03ef668_0
  - r-tidyselect=1.1.1=r36hc72bb7e_0
  - r-tidyverse=1.3.1=r36hc72bb7e_0
  - r-timedate=3043.102=r36h6115d3f_1002
  - r-tinytex=0.12=r36h6115d3f_0
  - r-ttr=0.24.2=r36hcdcec82_0
  - r-utf8=1.2.1=r36hcfec24a_0
  - r-uuid=0.1_4=r36hcdcec82_1
  - r-vctrs=0.3.8=r36hcfec24a_1
  - r-viridislite=0.4.0=r36hc72bb7e_0
  - r-waldo=0.2.5=r36hc72bb7e_0
  - r-withr=2.4.2=r36hc72bb7e_0
  - r-xfun=0.23=r36hcfec24a_0
  - r-xml2=1.3.2=r36h0357c0b_1
  - r-xtable=1.8_4=r36h6115d3f_3
  - r-xts=0.12.1=r36hcdcec82_0
  - r-yaml=2.2.1=r36hcfec24a_1
  - r-zoo=1.8_9=r36hcfec24a_0
  - readline=8.1=h46c0cb4_0
  - sed=4.8=he412f7d_0
  - send2trash=1.5.0=py_0
  - setuptools=49.6.0=py36h5fab9bb_3
  - simplegeneric=0.8.1=py_1
  - six=1.16.0=pyh6c4a22f_0
  - sqlite=3.35.5=h74cdb3f_0
  - sysroot_linux-64=2.12=h77966d4_13
  - terminado=0.10.0=py36h5fab9bb_0
  - testpath=0.5.0=pyhd8ed1ab_0
  - tk=8.6.10=h21135ba_1
  - tktable=2.10=hb7b940f_3
  - tornado=6.1=py36h8f6f2f9_1
  - traitlets=4.3.3=py36h9f0ad1d_1
  - typing_extensions=3.10.0.0=pyha770c72_0
  - wcwidth=0.2.5=pyh9f0ad1d_2
  - webencodings=0.5.1=py_1
  - wheel=0.36.2=pyhd3deb0d_0
  - xorg-kbproto=1.0.7=h7f98852_1002
  - xorg-libice=1.0.10=h7f98852_0
  - xorg-libsm=1.2.3=hd9c2040_1000
  - xorg-libx11=1.7.1=h7f98852_0
  - xorg-libxau=1.0.9=h7f98852_0
  - xorg-libxdmcp=1.1.3=h7f98852_0
  - xorg-libxext=1.3.4=h7f98852_1
  - xorg-libxrender=0.9.10=h7f98852_1003
  - xorg-renderproto=0.11.1=h7f98852_1002
  - xorg-xextproto=7.3.0=h7f98852_1002
  - xorg-xproto=7.0.31=h7f98852_1007
  - xz=5.2.5=h516909a_1
  - zeromq=4.3.4=h9c3ff4c_0
  - zipp=3.4.1=pyhd8ed1ab_0
  - zlib=1.2.11=h516909a_1010
  - zstd=1.5.0=ha95c52a_0
  - r-optparse
  - r-domc
  - r-devtools

Rename libraries for plink2R in the conda environment folder (as detailed here).

cd /users/xxx/scratch/miniconda3/envs/fusion_final/lib
mv liblapack.so libRlapack.so
mv libblas.so libRblas.so

Activate environment conda activate fusion_final.

Then in R, I installed plink2R using @carbocation's repository (thank you!) devtools::install_github("carbocation/plink2R/plink2R", ref="carbocation-permit-r361")