To encode strings in json, multiple reserved characters must be escaped with a backslash and each string must be enclosed in double quotes. The jsonlite package jsonlite implements this using the deparse function in the R database:
deparse_vector <- function(x) { stopifnot(is.character(x)) vapply(x, deparse, character(1), USE.NAMES=FALSE) }
This is the trick:
test <- c("line\nline", "foo\\bar", "I said: \"hi!\"") cat(deparse_vector(test))
However, deparse is slow for large vectors. An alternative implementation is to gsub each character separately:
deparse_vector2 <- function(x) { stopifnot(is.character(x)) if(!length(x)) return(x) x <- gsub("\\", "\\\\", x, fixed=TRUE) x <- gsub("\"", "\\\"", x, fixed=TRUE) x <- gsub("\n", "\\n", x, fixed=TRUE) x <- gsub("\r", "\\r", x, fixed=TRUE) x <- gsub("\t", "\\t", x, fixed=TRUE) x <- gsub("\b", "\\b", x, fixed=TRUE) x <- gsub("\f", "\\f", x, fixed=TRUE) paste0("\"", x, "\"") }
It is a little faster, but not very, very ugly. What would be the best way to do this? (preferably without additional dependencies)
This script can be used to compare implementations:
> system.time(out1 <- deparse_vector1(strings)) user system elapsed 6.517 0.000 6.523 > system.time(out2 <- deparse_vector2(strings)) user system elapsed 1.194 0.000 1.194