Skip to content

Instantly share code, notes, and snippets.

@SimonGreenhill
Created May 29, 2017 07:47
Show Gist options
  • Save SimonGreenhill/50573f58a317c936ef8331871bea6e7f to your computer and use it in GitHub Desktop.
Save SimonGreenhill/50573f58a317c936ef8331871bea6e7f to your computer and use it in GitHub Desktop.
Python code to compare the loaded packages in two R sessions
#!/usr/bin/env python3
#coding=utf-8
"""
Save the output of R's `sessionInfo()` into a text file.
"""
__author__ = 'Simon J. Greenhill <[email protected]>'
__copyright__ = 'Copyright (c) 2017 Simon J. Greenhill'
__license__ = 'New-style BSD'
import re
import codecs
is_counter = re.compile(r"""\[\d+\]""")
is_whitespace = re.compile(r"""\s+""")
def parse_package(package, rver=None):
package = package.split("_")
if len(package) == 1:
package = tuple([package[0], rver])
return tuple(package)
def parse_session(filename):
sections = {
'base': set(),
'packages': set(),
'namespace': set(),
}
rver = None
with codecs.open(filename, 'r', encoding="utf8") as handle:
section = None
for line in handle.readlines():
line = line.strip()
if len(line) == 0:
continue
elif line.startswith("R version"):
rver = is_whitespace.split(line)[2]
continue
elif line.strip() == 'attached base packages:':
section = 'base'
continue
elif line.strip() == 'other attached packages:':
section = 'packages'
continue
elif line.strip() == 'loaded via a namespace (and not attached):':
section = 'namespace'
continue
elif section is None:
continue
else:
line = is_counter.sub("", line)
line = [
parse_package(_, rver) for _ in is_whitespace.split(line) if len(_)
]
sections[section].update(line)
return sections
def match(package, packages):
try:
return [p for p in packages if p[0] == package][0]
except IndexError:
return None
def get_version(package):
if package is None:
return "Not Installed"
try:
return package[1]
except IndexError:
return None
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser(description='Does something.')
parser.add_argument("filename1", help='filename')
parser.add_argument("filename2", help='filename')
args = parser.parse_args()
s1 = parse_session(args.filename1)
s2 = parse_session(args.filename2)
for section in s1:
allp = [p[0] for p in s1[section]] + [p[0] for p in s2[section]]
for p in sorted(allp):
m1 = match(p, s1[section])
m2 = match(p, s2[section])
if m1 != m2:
print(
section.ljust(10), p.ljust(10),
get_version(m1).ljust(10),
get_version(m2)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment