Packages R sur BioConductor via SVN

Le notebook BioConductor explique comment récupérer la liste des paquets depuis la page publique de BioConductor, ainsi que les méta-données associées à ces packages. Il existe une alternative pour obtenir ces méta-données, directement depuis les fichiers DESCRIPTION des packages.

La page suivante donne un accès à la liste des paquets R hébergés sur leur svn : https://hedgehog.fhcrc.org/bioconductor/branches/RELEASE_3_0/madman/Rpacks/ (username/password : readonly)

De ce listing, chaque sous-répertoire est un package et contient potentiellement un fichier DESCRIPTION. Nous allons récupérer et parser ces fichiers.


In [2]:
import requests

URL = 'https://hedgehog.fhcrc.org/bioconductor/branches/RELEASE_3_0/madman/Rpacks/'
URL_DESCR = 'https://hedgehog.fhcrc.org/bioconductor/branches/RELEASE_3_0/madman/Rpacks/{name}/DESCRIPTION'

content = requests.get(URL, auth=requests.auth.HTTPBasicAuth('readonly', 'readonly')).content

In [17]:
import BeautifulSoup as bs

soup = bs.BeautifulSoup(content)

names = []
for anchor in soup.find('ul').findAll('a'):
    names.append(anchor['href'][:-1])
    
# Remove '..'
names.pop(0)


Out[17]:
u'..'

Pour chaque candidat package, nous attaquons l'adresse du DESCRIPTION que nous parsons à l'aide de la fonction suivante.


In [16]:
def parse_DESCRIPTION(content):
    r = {}
    for line in content.split('\n'):
        if len(line.strip()) > 0:
            if line.startswith((' ', '\t')):
                r[key] += ' ' + line.strip() # key is already defined in this case
            else:
                try:
                    key, value = line.split(':', 1)
                    r[key.strip()] = value.strip()
                except Exception as e:
                    print line
                    print 'len is', len(line)
                    print '---'
                    print content
                    print '---'
                    # raise
    return r

In [19]:
packages = {}
errors = []

for name in names:
    r = requests.get(URL_DESCR.format(name=name), auth=requests.auth.HTTPBasicAuth('readonly', 'readonly'))
    if r.status_code == 200:
        packages[name] = parse_DESCRIPTION(r.content)
    else:
        errors.append(name)

In [20]:
len(packages), len(errors), len(names)


Out[20]:
(1001, 30, 1031)

In [30]:
import pandas

df = pandas.DataFrame.from_dict(packages, orient='index')
df = df.drop_duplicates('Package')
df.to_csv('../data/bioconductorsvn_description.csv')