I have .bib file (downloaded from web of science) and I want to import it into R, replace all instances of "in light of" with "CONSIDERING", and export it as a .bib file. I have not been able to find a function that can write my data back to a .bib file. WriteBib does not work because refs is a "pairlist" object, not "bibentry". Any advice on how to export a .bib file that can be imported into Mendeley? thanks for your help!
here is the code:
library(bibtex)
library(RefManageR)
refs = do_read_bib("/Users/CarrieAnn/Downloads/savedrecs (1).bib", encoding = "unknown", srcfile)
for (i in 1:length(refs)) {
refs[[i]] = gsub("in light of", "CONSIDERING", refs[[i]])
}
I think your easiest option is to treat the .bib file like a normal text file. Try this:
raw_text <- readLines("example.bib")
new_text <- gsub("in light of", "CONSIDERING", raw_text)
writeLines(new_text, con="new_example.bib")
Contents of example.bib:
% a sample bibliography file
%
#article{small,
author = {Doe, John},
title = {A small paper},
journal = {The journal of small papers},
year = 1997,
volume = {-1},
note = {in light of recent events},
}
#article{big,
author = {Smith, Jane},
title = {A big paper},
journal = {The journal of big papers},
year = 7991,
volume = {MCMXCVII},
note = {in light of what happened},
}
Output of new_example.bib:
% a sample bibliography file
%
#article{small,
author = {Doe, John},
title = {A small paper},
journal = {The journal of small papers},
year = 1997,
volume = {-1},
note = {CONSIDERING recent events},
}
#article{big,
author = {Smith, Jane},
title = {A big paper},
journal = {The journal of big papers},
year = 7991,
volume = {MCMXCVII},
note = {CONSIDERING what happened},
}
A bit of explanation:
BibEntry objects have non-standard internals and are hard to work with, outside of the functionality provided in the RefManageR package. As soon as you unclass or reduce a BibEntry object to a list, it becomes difficult to put back into a bib format, due to the object's required mix of fields and attributes. (And to make matters worse, bibtex and RefManageR don't have exactly the same internal structure, so it's hard to convert from one context to the other.)
Try changing your code like this (make sure to use read.bib function and in the loop, reference the fields in which the text you want to change appears, e.g. "note" or "title". For the example file supplied by #andrew_reece, it should work like this:
refs = read.bib("example.bib", encoding = "unknown", srcfile)
for (i in 1:length(refs)) {
refs$note[i] = gsub("in light of", "CONSIDERING", refs$note[i])
}
WriteBib(as.BibEntry(refs), "example2.bib")
However, based on your task description, I agree with #andrew_reece that treating bib files as plain text is easier (on the other hand, for larger bib files, you may actually want to exercise more control over which fields you are substituting.)
Related
Is there an (easy) way to automatically generate a publication list (from a bib-file) on Quarto website using R?
I plan to build a new academic website using quarto. To reduce the weekly/monthly maintenance load, I intend to structure/organize/build this page to fulfill multiple purposes at once. The site should not only be a classic academic website but also provide the basics for my CV. Hence, I want to generate the CV directly from this website. That seems to be pretty easy using Quarto and combining the .qmd files for a PDF.
However, I also want to use a bib-file of my publications to automatically generate a publication list. I want to list them categorized by type (#article or #book) and in descending chronological order (2022, 2021, 2020).
In addition, I want to add two other features to this list. First, I want to add numbers per category to each publication, so that the first publication in the category #book receives [1], the second [2] and so on. Second, I want to highlight (bold text) my name (e.g., John Doe) when there are multiple authors for a publication.
Is there an easy way to use R in Quarto for getting such an output?
I have attached some example bib-file entries:
#article{Doe2022b,
author = {Doe, John},
date-added = {2022-11-20 09:36:34 +0100},
date-modified = {2022-11-20 09:37:52 +0100},
doi = {10.1109/5.771073},
journal = {Daily Prophet},
number = {3},
pages = {1-25},
title = {I still know it better},
volume = {25},
year = {2020},
bdsk-url-1 = {https://doi.org/10.1109/5.771073}}
#article{Doe2020,
author = {Doe, Jane and Doe, John},
date-added = {2022-11-20 09:34:29 +0100},
date-modified = {2022-11-20 09:36:30 +0100},
doi = {10.1109/5.771073},
journal = {Daily Prophet},
number = {1},
pages = {18-35},
title = {We know it better},
volume = {23},
year = {2020}}
#book{Doe2021,
address = {Hogwarts},
author = {Doe, John},
date-added = {2022-11-20 09:34:11 +0100},
date-modified = {2022-11-20 09:34:19 +0100},
publisher = {Flourish and Blotts},
title = {My first Book},
year = {2021}}
#book{Doe2022,
address = {Hogwarts},
author = {Doe, John},
date-added = {2022-11-20 09:32:15 +0100},
date-modified = {2022-11-20 09:33:56 +0100},
publisher = {Flourish and Blotts},
title = {My second Book},
year = {2022}}
I'm not aware of any existing tool that does what you need. If you want to build it yourself, then use Quarto's Lua support to do so.
For example, to generate a list off all books, you'd write a Lua file like this:
-- This is `books-section.lua`
local function is_book (ref)
return ref.type == 'book'
end
function Pandoc (doc)
local references = pandoc.utils.references(doc)
local books = references:filter(is_book)
doc.meta.references = books
doc.meta.bibliography = nil -- ensure that only books will be used
doc.blocks = pandoc.Blocks{
pandoc.Header(1, 'Books'),
pandoc.Div({}, 'refs')
}
return pandoc.utils.citeproc(doc)
end
and then use it to generate a "Book" section with
quarto pandoc -L books-section.lua my-bibliography.bib \
--to=markdown-citations -o books.qmd
The Lua integration is quite powerful, so you might be able to do everything you need and to integrate the whole process into the normal website generation. See the Quarto docs on Lua development for more details.
I use the following to create a D2L exam from the "capital.Rmd" example (I converted the question to schoice)
exams2blackboard("capitals.Rmd", n =3, name = "testquiz" )
After I upload the testquiz.zip file, I notice that the correct answer must be manually chosen on the D2L platform.
I was wondering if there is a workaround.
Many Thanks,
Umut
If you want the correct solution to be selected, do not use the Import option from the Question Library or from the Quiz itself. Use the Import/Export/Copy Components under the Course Admin tab.
If you import the questions through the following steps, BrightSpace correctly picks the right solution. It’s a bit longer but seems to correctly choose the solution.
Under the Course Admin tab of your course, go to
'Import/Export/Copy Components' -> ‘Import Components’ -> Start -> (drag and drop the ZIP file)
Click ‘Advanced Options…’
This step will take a few minutes for large files; if you do not click
Advanced Options, then the import will automatically import the
questions into the 'Question Library' and will generate a Quiz with the
imported questions; you do not want this.
-> Continue -> Continue -> at this point choose 'Question Library' from the section 'Select Components to Import'
I would not choose ‘Quizzes’ because it automatically creates a quiz
and makes it available to students. It has the unfortunate side-effect
of making ALL the questions available, which means all the versions of
various dynamic questions; this is not something we want.
-> Continue -> Continue. This stage takes a few minutes for large
imports.
Now the Questions are available in the Question Library and can be used to generate new quizzes. Each question has the correct answer selected already. This works for ‘schoice’ and ‘mchoice’ versions of questions. Currently, plots are not imported, though, still trying to figure out why.
This problem is new to me. In earlier versions of Brightspace/D2L the import of single-choice and multiple-choice exercises via exams2blackboard() worked well. Possibly, D2L changed in the meantime given that neither the current release version from CRAN nor the development version from R-Forge work for you.
D2L also supports other import formats and we did play around with some of these. See the following discussions in the R/exams forum on R-Forge:
https://R-Forge.R-project.org/forum/forum.php?thread_id=33404&forum_id=4377&group_id=1337
https://R-Forge.R-project.org/forum/forum.php?thread_id=33657&forum_id=4377&group_id=1337
Notably we tried to use the XML-based QTI 2.1 format that seems to be employed by D2L internally. However, D2L apparently uses a particular custom flavor of QTI 2.1. It should be possible to reverse engineer that and improve exams2qti21() correspondingly but so far (to the best of my knowledge) no one put the time and effort into this that would be needed.
For simple single/multiple choice questions a CSV-based exchange format can also be used. I have put together a very basic exams2d2l() function that was posted in the threads above and that I'm also including below. It can set up the CSV file for a single exercise like the capitals.Rmd exercise that you use above. For plain text exercises like that it seems to work well but not for more complex elements (graphics, code, math, etc.).
exams2d2l <- function(file, dir = ".", ## n = 1L, nsamp = NULL disabled for now
name = NULL, quiet = TRUE, edir = NULL, tdir = NULL, sdir = NULL, verbose = FALSE,
resolution = 100, width = 4, height = 4, svg = FALSE,
encoding = "", converter = NULL, ...)
{
## for Rnw exercises use "ttm" converter otherwise "pandoc" converter
if(any(tolower(tools::file_ext(unlist(file))) == "rmd")) {
if(is.null(converter)) converter <- "pandoc"
} else {
if(is.null(converter)) converter <- "ttm"
}
## output directory or display on the fly
## output name processing
if(is.null(name)) name <- tools::file_path_sans_ext(basename(file))
## set up .html transformer and writer function
htmltransform <- make_exercise_transform_html(converter = converter, ...)
## create exam with HTML text
rval <- xexams(file,
driver = list(sweave = list(quiet = quiet, pdf = FALSE, png = !svg, svg = svg,
resolution = resolution, width = width, height = height, encoding = encoding),
read = NULL, transform = htmltransform, write = NULL),
dir = dir, edir = edir, tdir = tdir, sdir = sdir, verbose = verbose)
## currently: only a single exercise
rval <- rval[[1L]][[1L]]
## put together CSV
cleanup <- function(x) gsub('"', '""', paste(x, collapse = "\n"), fixed = TRUE)
rval <- c(
'NewQuestion,MC,,,',
sprintf('ID,"%s",,,', cleanup(rval$metainfo$file)),
sprintf('Title,"%s",,,', cleanup(rval$metainfo$name)),
sprintf('QuestionText,"%s",,,', cleanup(rval$question)),
sprintf('Points,%s,,,', if(is.null(rval$metainfo$points)) 1 else rval$metainfo$points),
'Difficulty,1,,,',
'Image,,,,',
paste0('Option,', ifelse(rval$metainfo$solution, 100, 0), ',"', cleanup(rval$questionlist), '",,"', cleanup(rval$solutionlist), '"'),
'Hint,,,,',
sprintf('Feedback,"%s",,,', cleanup(rval$solution))
)
writeLines(rval, file.path(dir, paste0(name, ".csv")))
invisible(rval)
}
I am able to see every database in the .rdb file in the variable environment as a "promise" as per direction here. Now, I want to edit one of the file and save it. How can I do that? I am new in R.
In a discussion on r-pkg-devel, Ivan Krylov provided the following function ro read an RDB database:
# filename: the .rdb file
# offset, size: the pair of values from the .rdx
# type: 'gzip' if $compressed is TRUE, 'bzip2' for 2, 'xz' for 3
readRDB <- function(filename, offset, size, type = 'gzip') {
f <- file(filename, 'rb')
on.exit(close(f))
seek(f, offset + 4)
unserialize(memDecompress(readBin(f, 'raw', size - 4), type))
}
Therefore, you should be able to implement the reverse using a combination of serialize, memCompress, and writeBin.
Note that if the object changes size, you will also have to adjust the index file.
I will have to generate a gantt diagram in a daily basis. My idea is to use the mermaid api included in R's DiagrammeR package.
My data will always have the same structure and, therefore, I have created a quite primitive parser that is included in the reproducible example.
The problem I face is that after 4 sections the styling starts again from zero:
rect.section.section0
rect.section.section1
rect.section.section2
rect.section.section3
rect.section.section0
I can change rect.section.sectionx colour from the .css but I cannot add new ones.
Is there a way around to change/personalise the section's colour/styling?
My R reproducible example:
library(DiagrammeR)
library(htmltools)
fromdftogantt<-function(df,Title="Proba",filename="proba.html"){
txt<-paste("gantt","dateFormat YYYY-MM-DD",paste("title",Title),"",sep="\n")
for(i in unique(df$section)){
txt<-paste(txt,paste("section",i),sep="\n")
for(j in which(df$section==i)){
txt<-paste(txt,paste0(df$name[j],":",df$status[j],",",
df$fecini[j],",",
df$fecfin[j]),sep="\n")
}
txt<-paste0(txt,"\n")
}
m<-mermaid(txt)
m$x$config = list(ganttConfig = list(
axisFormatter = list(list(
"%m-%Y"
,htmlwidgets::JS(
'function(d){ return d.getDate() == 1 }'
)
))
))
save_html(as.tags(m),file=filename)
}
df<-data.frame(section=letters[1:6],name=paste("Name",1:6),
status=rep("active",6),
fecini=as.Date(c("2015-02-03","2015-03-05","2015-04-07",
"2015-02-03","2015-03-05","2015-04-07")),
fecfin=as.Date(c("2015-06-01","2015-04-30","2015-12-31",
"2015-06-01","2015-04-30","2015-12-31")),
stringsAsFactors = FALSE)
fromdftogantt(df,Title="Proba",filename="proba.html")
You don't need to change the .js file at all. mermaid supports a numberSectionStyles config parameter. Just add the following line to your R function before saving the HTML:
m$x$config$ganttConfig$numberSectionStyles = 6
You'll still need to adjust the .css file to add the additional sections following the same template as the existing ones.
How can I easily import citations from R into endnote obtained by for instance
citation("ggplot2")
Is there a good workflow for this or do I manually have to do it?
How automated this can be will depend on what Endnote can import. It seems BibTeX import is not currently possible out of the box, and requires some extra software. See for example: http://www.lib.uts.edu.au/content/faq/how-can-i-import-bibliography-endnote-bibtex-latex-what-about-converting-other-way-endno
Read ?bibentry and in particular the argument style and the Details section. See if Endnote can import data in any of those formats? I doubt it, but I have never used Endnote.
If not, we can go the BibTeX route if you install something that allows you to import BibTeX into Endnote.
> utils:::print.bibentry(citation("ggplot2"), style = "Bibtex")
#Book{,
author = {Hadley Wickham},
title = {ggplot2: elegant graphics for data analysis},
publisher = {Springer New York},
year = {2009},
isbn = {978-0-387-98140-6},
url = {http://had.co.nz/ggplot2/book},
}
To get this out into a file for passing to an import utility, you can use capture.output()
capture.output(utils:::print.bibentry(citation("ggplot2"), style = "Bibtex"),
file = "endnote_import.bib")
Which gives a file with the following content:
$ cat endnote_import.bib
#Book{,
author = {Hadley Wickham},
title = {ggplot2: elegant graphics for data analysis},
publisher = {Springer New York},
year = {2009},
isbn = {978-0-387-98140-6},
url = {http://had.co.nz/ggplot2/book},
}
which you should be able to import with third party tools.