Michael Friendly
2011-Dec-16 13:46 UTC
[Rd] R package BibTex entries: looking for a more general solution
Back in 2010 I raised this issue, and there was some discussion,
https://stat.ethz.ch/pipermail/r-devel/2010-November/058987.html
The goal, then, as now is to have a way to produce a bibtex-clean .bib
file (i.e., not requiring
manual editing except in unusual circumstances) reflecting installed
packages
for use in writing where one often needs/wants to cite all packages used
in a given article.
Achim wrote the function below which largely does this job, quite
nicely now that most
DESCRIPTION files now contain Authors@R fields. However, something
changed since
R 2.11.1 when I tried this last, so that the function no longer
generates keys for packages
which contain *more than one citation*.
I've tried debugging with browser(), but can't figure out how to make
the lines around FIXME
work. Can someone help?
You can see the result from this at
http://euclid.psych.yorku.ca/SCS/Private/Rbibs/Rpackages-2.14.0.bib
The function is also at:
# Original code by Achim Zeileis, 16 Dec 2009, R-help
# Added: support header and preamble
Rpackages.bib <- function(filename =
paste("Rpackages-",getRversion(),
".bib", sep=""),
header=TRUE, preamble=NULL, suppress.warnings=TRUE, verbose = TRUE)
{
## installed packages
pkgs <- unique(installed.packages()[,1])
if (suppress.warnings) warn <- options(warn=-1)
bibs <- lapply(pkgs, function(x) try(toBibtex(citation(x))))
if (suppress.warnings) options(warn)
n.installed <- length(bibs)
## omit failed citation calls
ok <- !(sapply(bibs, class) == "try-error")
pkgs <- pkgs[ok]
bibs <- bibs[ok]
n.converted <- sum(ok)
## unify to list of Bibtex
bibs <- lapply(bibs, function(x) if(inherits(x, "Bibtex"))
list(x)
else x)
## FIXME: add bibtex keys to each entry [the line below does not work!!]
pkgs <- lapply(seq_along(pkgs), function(i) if(length(bibs[[i]]) > 1)
paste(pkgs[i], 1:length(bibs[[i]]), sep = "") else pkgs[i])
pkgs <- do.call("c", pkgs)
bibs <- do.call("c", bibs)
for(i in seq_along(pkgs)) bibs[[i]][1] <-
gsub("{,", paste("{", pkgs[i], ",", sep =
""), bibs[[i]][1], fixed
= TRUE)
if(header) header <- gsub("^", "%",
toLatex(sessionInfo()))
output <- file(filename, "a")
cat(header, preamble, sep='\n', file=output, append=TRUE)
## write everything to a single .bib file
writeLines(do.call("c", lapply(bibs, as.character)), con=output)
close(output)
if(verbose) cat("Converted", n.converted, "of",
n.installed,
"package citations to BibTeX",
"\nResults written to file", filename, "\n")
## return Bibtex items invisibly
invisible(bibs)
}
--
Michael Friendly Email: friendly AT yorku DOT ca
Professor, Psychology Dept.
York University Voice: 416 736-5115 x66249 Fax: 416 736-5814
4700 Keele Street Web: http://www.datavis.ca
Toronto, ONT M3J 1P3 CANADA
[[alternative HTML version deleted]]
Achim Zeileis
2011-Dec-16 14:51 UTC
[Rd] R package BibTex entries: looking for a more general solution
Michael,
meanwhile the "bibentry" class that Kurt mentioned back in the
discussion
in 2010 is fully implemented in R. Hence the code can be simplified when
working with the "bibentry" objects directly (instead of the
"Bibtex"
objects derived from them).
I've quickly hacked some code to illustrate how the function needs to be
modified but I didn't have the time to integrate it into the function
(I'm currently traveling).
## query packages and their bibentries
? pkgs <- unique(installed.packages()[,1])
? bibs <- lapply(pkgs, function(x) try(citation(x)))
## exclude those with errors
? ok <- !(sapply(bibs, class) == "try-error")
? pkgs <- pkgs[ok]
? bibs <- bibs[ok]
## number of bibentries per package
nref <- sapply(bibs, length)
## merge all bibentries
bibs <- do.call("c", bibs)
## add citation keys
bibkeys <- lapply(1:length(nref), function(i)
if(nref[i] > 1) paste(pkgs[i], 1:nref[i], sep = ":") else
pkgs[i])
bibs$key <- as.list(unlist(bibkeys))
And then you just need to say toBibtex(bibs) or writeLines(toBibtex(bibs))
or something along those lines.
For more details on the new classes, see this recent working paper by Kurt
Duncan and myself: http://epub.wu.ac.at/3269/.
So much for today.
Best wishes,
Z
On Fri, 16 Dec 2011, Michael Friendly wrote:
> Back in 2010 I raised this issue, and there was some discussion,
>
> https://stat.ethz.ch/pipermail/r-devel/2010-November/058987.html
>
> The goal, then, as now is to have a way to produce a bibtex-clean .bib file
> (i.e., not requiring
> manual editing except in unusual circumstances) reflecting installed
> packages
> for use in writing where one often needs/wants to cite all packages used in
> a given article.
>
> Achim wrote the function below? which largely does this job, quite nicely
> now that most
> DESCRIPTION files now contain Authors at R fields.? However, something
changed
> since
> R 2.11.1 when I tried this last, so that the function no longer generates
> keys for packages
> which contain more than one citation.
>
> I've tried debugging with browser(), but can't figure out how to
make the
> lines around FIXME
> work.? Can someone help?
>
> You can see the result from this at
> http://euclid.psych.yorku.ca/SCS/Private/Rbibs/Rpackages-2.14.0.bib
> The function is also at:
>
> # Original code by Achim Zeileis, 16 Dec 2009, R-help
> # Added: support header and preamble
>
> Rpackages.bib <- function(filename =
paste("Rpackages-",getRversion(),
> ".bib", sep=""),
> ??? ??? header=TRUE, preamble=NULL, suppress.warnings=TRUE, verbose = TRUE)
> {
> ? ## installed packages
> ? pkgs <- unique(installed.packages()[,1])
> ? if (suppress.warnings) warn <- options(warn=-1)
> ? bibs <- lapply(pkgs, function(x) try(toBibtex(citation(x))))
> ? if (suppress.warnings) options(warn)
> ?
> ? n.installed <- length(bibs)
>
> ? ## omit failed citation calls
> ? ok <- !(sapply(bibs, class) == "try-error")
> ? pkgs <- pkgs[ok]
> ? bibs <- bibs[ok]
> ? n.converted <- sum(ok)
> ? ## unify to list of Bibtex
> ? bibs <- lapply(bibs, function(x) if(inherits(x, "Bibtex"))
list(x) else x)
>
> ? ## FIXME: add bibtex keys to each entry [the line below does not work!!]
> ? pkgs <- lapply(seq_along(pkgs), function(i) if(length(bibs[[i]]) >
1)
> ??? paste(pkgs[i], 1:length(bibs[[i]]), sep = "") else pkgs[i])
> ? pkgs <- do.call("c", pkgs)
> ? bibs <- do.call("c", bibs)
> ? for(i in seq_along(pkgs)) bibs[[i]][1] <-
> ??? gsub("{,", paste("{", pkgs[i], ",", sep =
""), bibs[[i]][1], fixed > TRUE)
>
> ??? if(header) header <- gsub("^", "%",
toLatex(sessionInfo()))
> ??? output <- file(filename, "a")
> ??? cat(header, preamble, sep='\n', file=output, append=TRUE)
> ? ## write everything to a single .bib file
> ? writeLines(do.call("c", lapply(bibs, as.character)),
con=output)
> ? close(output)
> ? if(verbose) cat("Converted", n.converted, "of",
n.installed,
> ??? "package citations to BibTeX",
> ??? "\nResults written to file", filename, "\n")
>
> ? ## return Bibtex items invisibly
> ? invisible(bibs)
> }
>
>
>
>
>
>
> --
> Michael Friendly Email: friendly AT yorku DOT ca
> Professor, Psychology Dept.
> York University Voice: 416 736-5115 x66249 Fax: 416 736-5814
> 4700 Keele Street Web: http://www.datavis.ca
> Toronto, ONT M3J 1P3 CANADA
>
>
Renaud Gaujoux
2011-Dec-19 07:02 UTC
[Rd] R package BibTex entries: looking for a more general solution
Hi,
I actually adapted and integrated this feature into Achim's -- nice --
function (posted on r-help).
Romain included it a couple of weeks ago into the bibtex package as
function write.bib, and submitted the update to CRAN, but some NOTEs in
the check delayed its availability on CRAN.
You can still install and try out the new version with:
install.packages("bibtex",
repos="http://R-Forge.R-project.org")
Keys for multiple citations are generated as "<pkgname>%i",
which might
not be ideal, but works ok though. It might be better not number the
first (main) citation. Romain, I think I will submit a patch for this.
Hope this helps.
Renaud
--
Renaud Gaujoux
Computational Biology - University of Cape Town
South Africa