Q2 plugin with R script issue

plugin-development

(John Chase) #1

Hi all,

I am creating a QIIME2 plugin similar to the DADA2 plugin, however when I install my plugin the R script is executed as though it is a python script, this of course results in errors as it is not valid python code.

Here is a small example of what I am referring to.

The directory structure is as follows:

test-r/  
    run_test.R  
    setup.py

the contents of setup.py are:

from setuptools import setup

setup(
    name='q2-test-r',
    scripts=['run_test.R'],
    entry_points={
        'qiime2.plugins':
        ['q2-phylofactor=q2_phylofactor.plugin_setup:plugin']
    },
)

and the contents of run_test.R are:

#!/usr/bin/env Rscript

R.version

I installed the package pip install -e .

and when I run the script:

$run_test.R
Traceback (most recent call last):
  File "/Users/jc33/miniconda3/envs/qiime2-dev/bin/run_test.R", line 6, in <module>
    exec(compile(open(__file__).read(), __file__, 'exec'))
  File "/Users/jc33/dev/test-r/run_test.R", line 3, in <module>
    R.version
NameError: name 'R' is not defined

This works as expected when I run it with:

Rscript run_test.R

Though this is obviously a contrived sample the behavior is identical in the actual plugin I am developing. In the plugin the R script is called from within a python script using subprocess, but in both cases it is being run as though it is a Python script.

The DADA2 plugin works with no issues, so I am clearly missing something, however I am totally stumped as to what that is. Any help is much appreciated.


(Matthew Ryan Dillon) #2

(Evan Bolyen) #3

That makes no sense, I’m stumped as well.

Does prepending Rscript to your subprocess command change anything?

Also, the scripts= section of setup.py isn’t mirrored by pip install -e ., so you have to re-install when those scripts change (which is super annoying). Is there any chance you’ve got a cached script which is just wrong?

What does cat $(which run_test.R) say?


(Evan Bolyen) #4

(John Chase) #5

I tried that, however in doing that the that results in a file not found error, or something like that as it is not looking in my PATH

cat $(which run_test.R)

# EASY-INSTALL-DEV-SCRIPT: 'q2-rtest==0.0.0','run_test.R'
__requires__ = 'q2-rtest==0.0.0'
__import__('pkg_resources').require('q2-rtest==0.0.0')
__file__ = '/Users/jc33/dev/q2-rtest/q2_rtest/assets/run_test.R'
exec(compile(open(__file__).read(), __file__, 'exec'))

(John Chase) #6

For anyone running into this issue in the future @ebolyen Solved this issue on Stack Overflow https://stackoverflow.com/a/50380713/3639023

The idea is that if the R code looks like python (i.e. despite being valid R doesn’t throw a python SyntaxError or TypeError) and therefore easy_install makes a wrapper script.


(Evan Bolyen) #7

That was a tough one to figure out too! I ended up just deleting code until it stopped working. Eventually I was left with just an R script so I started removing code from that.


(Matthew Ryan Dillon) #8

Computers are the worst. Glad you got this sorted out! :t_rex::t_rex::t_rex:


(John Chase) #9

Thanks for your help on this @ebolyen, it is much appreciated!