diff --git a/NAMESPACE b/NAMESPACE index fb38b48..2adf300 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -19,6 +19,7 @@ export(from_json) export(minify_json) export(pretty_json) export(to_json) +export(to_ndjson) export(validate_json) importFrom(Rcpp,sourceCpp) useDynLib(jsonify, .registration = TRUE) diff --git a/R/to_json.R b/R/to_json.R index cc3ed8e..004b467 100644 --- a/R/to_json.R +++ b/R/to_json.R @@ -52,6 +52,20 @@ to_json <- function( x, unbox = FALSE, digits = NULL, numeric_dates = TRUE, rcpp_to_json( x, unbox, digits, numeric_dates, factors_as_string, by ) } +#' To ndjson +#' +#' Converts R objects to ndjson +#' +#' +#' @export +to_ndjson <- function( x, unbox = FALSE, digits = NULL, numeric_dates = TRUE, + factors_as_string = TRUE, by = "row" ) { + if( "col" %in% by ) by <- "column" + by <- match.arg( by, choices = c("row", "column") ) + digits <- handle_digits( digits ) + rcpp_to_ndjson( x, unbox, digits, numeric_dates, factors_as_string, by ) +} + handle_digits <- function( digits ) { if( is.null( digits ) ) return(-1) return( as.integer( digits ) ) diff --git a/inst/include/jsonify/to_json/api.hpp b/inst/include/jsonify/to_json/api.hpp index ba06c56..9dd9490 100644 --- a/inst/include/jsonify/to_json/api.hpp +++ b/inst/include/jsonify/to_json/api.hpp @@ -102,38 +102,61 @@ namespace api { std::ostringstream os; // for storing the final string of ndjson - for( row = 0; row < n_row; row++ ) { - - // create new stream each row - rapidjson::StringBuffer sb; - rapidjson::Writer < rapidjson::StringBuffer > writer( sb ); - + if( by == "row" ) { - writer.StartObject(); + for( row = 0; row < n_row; row++ ) { + + // create new stream each row + rapidjson::StringBuffer sb; + rapidjson::Writer < rapidjson::StringBuffer > writer( sb ); + + writer.StartObject(); + for( df_col = 0; df_col < n_cols; df_col++ ) { + + const char *h = column_names[ df_col ]; + writer.String( h ); + + SEXP this_vec = df[ h ]; + + switch( TYPEOF( this_vec ) ) { + + case VECSXP: { + Rcpp::List lst = Rcpp::as< Rcpp::List >( this_vec ); + jsonify::writers::complex::write_value( writer, lst, unbox, digits, numeric_dates, factors_as_string, by, row, in_data_frame ); + break; + } + default: { + jsonify::writers::complex::switch_vector( writer, this_vec, unbox, digits, numeric_dates, factors_as_string, row ); + } + } // end switch + + } // end for + writer.EndObject(); + + os << sb.GetString(); + os << '\n'; + } // end for (row) + + } else { + // by == "column" for( df_col = 0; df_col < n_cols; df_col++ ) { + // create new stream each row + rapidjson::StringBuffer sb; + rapidjson::Writer < rapidjson::StringBuffer > writer( sb ); + + writer.StartObject(); const char *h = column_names[ df_col ]; writer.String( h ); - SEXP this_vec = df[ h ]; + jsonify::writers::complex::write_value( writer, this_vec, unbox, digits, numeric_dates, factors_as_string, by, -1, in_data_frame ); - switch( TYPEOF( this_vec ) ) { - - case VECSXP: { - Rcpp::List lst = Rcpp::as< Rcpp::List >( this_vec ); - jsonify::writers::complex::write_value( writer, lst, unbox, digits, numeric_dates, factors_as_string, by, row, in_data_frame ); - break; - } - default: { - jsonify::writers::complex::switch_vector( writer, this_vec, unbox, digits, numeric_dates, factors_as_string, row ); - } - } // end switch + writer.EndObject(); - } // end for - writer.EndObject(); + os << sb.GetString(); + os << '\n'; + } // end for (column) - os << sb.GetString(); - os << '\n'; } Rcpp::StringVector sv = os.str(); diff --git a/man/to_ndjson.Rd b/man/to_ndjson.Rd new file mode 100644 index 0000000..ce238c4 --- /dev/null +++ b/man/to_ndjson.Rd @@ -0,0 +1,12 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/to_json.R +\name{to_ndjson} +\alias{to_ndjson} +\title{To ndjson} +\usage{ +to_ndjson(x, unbox = FALSE, digits = NULL, numeric_dates = TRUE, + factors_as_string = TRUE, by = "row") +} +\description{ +Converts R objects to ndjson +}