Skip to content

Commit

Permalink
Merge pull request #3 from colearendt/developclean
Browse files Browse the repository at this point in the history
Development with Clean History
  • Loading branch information
colearendt authored Jun 15, 2017
2 parents 68887e1 + f6f13f4 commit 168b4d7
Show file tree
Hide file tree
Showing 85 changed files with 2,453 additions and 445 deletions.
5 changes: 5 additions & 0 deletions .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,8 @@
^codecov\.yml$
^README\.Rmd$
^README-.*\.png$
^packrat/
^\.Rprofile$
^working/
^appveyor\.yml$
^revdep/
4 changes: 4 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
* text=auto
data/* binary
src/* text=lf
R/* text=lf
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,7 @@ inst/doc
.Rproj.user
*.Rproj
.DS_Store
packrat/lib*/
packrat/src/
working/
.Rprofile
8 changes: 8 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ cache: packages

r_packages:
- covr

script:
- |
travis_wait 60 R CMD build --no-build-vignettes --no-manual --no-resave-data .
travis_wait 60 R CMD check --no-build-vignettes --no-manual tidyjson*tar.gz
after_success:
- Rscript -e 'library(covr); codecov()'

after_script:
- ./travis-tool.sh dump_logs
7 changes: 4 additions & 3 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: tidyjson
Title: Tidy Complex JSON
Version: 0.2.1.9000
Version: 0.2.1.9001
Author: Jeremy Stanley <[email protected]>
Maintainer: Jeremy Stanley <[email protected]>
Description: Turn complex JSON data into tidy data frames.
Expand Down Expand Up @@ -28,8 +28,9 @@ Suggests:
listviewer,
igraph,
RColorBrewer,
covr
covr,
lubridate
VignetteBuilder: knitr
URL: https://github.com/jeremystan/tidyjson
BugReports: https://github.com/jeremystan/tidyjson/issues
RoxygenNote: 5.0.1
RoxygenNote: 6.0.1
16 changes: 16 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
@@ -1,26 +1,39 @@
# Generated by roxygen2: do not edit by hand

S3method("[",tbl_json)
S3method(arrange,tbl_json)
S3method(arrange_,tbl_json)
S3method(as.character,tbl_json)
S3method(as.tbl_json,character)
S3method(as.tbl_json,data.frame)
S3method(as.tbl_json,tbl_json)
S3method(filter,tbl_json)
S3method(filter_,tbl_json)
S3method(mutate,tbl_json)
S3method(mutate_,tbl_json)
S3method(print,tbl_json)
S3method(slice,tbl_json)
S3method(slice_,tbl_json)
export("%>%")
export(append_chr)
export(append_dbl)
export(append_lgl)
export(append_values_logical)
export(append_values_number)
export(append_values_string)
export(as.tbl_json)
export(as_data_frame)
export(as_tibble)
export(bind_rows)
export(enter_object)
export(gather_array)
export(gather_keys)
export(gather_object)
export(is.tbl_json)
export(is_json_array)
export(is_json_chr)
export(is_json_dbl)
export(is_json_lgl)
export(is_json_logical)
export(is_json_null)
export(is_json_number)
Expand All @@ -29,8 +42,11 @@ export(is_json_scalar)
export(is_json_string)
export(jlogical)
export(jnumber)
export(json_chr)
export(json_complexity)
export(json_dbl)
export(json_lengths)
export(json_lgl)
export(json_schema)
export(json_structure)
export(json_types)
Expand Down
37 changes: 36 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,39 @@
# purrr 0.2.1.9000
# tidyjson 0.2.1.9001

## New functions

* Add `bind_rows()` support. Though currently not an S3 implementation, it behaves as much like the `dplyr` variant as possible, preserving the `attr(.,'JSON')` components if all components are `tbl_json` objects. (#58)

## Documentation Changes

* "Using Multiple APIs" vignette added to show support for using tidyjson with multiple APIs (#85)

* Updated README.md to better explain `spread_all()` (#92)

## Bug fixes and minor changes

* `DROP=TRUE` caused an error. Altered behavior to be consistent with `tbl_df` (throw a warning and do nothing)

* Fix `spread_all(recursive=FALSE)` bug that caused an error (#65)

* Alter `spread_all()` behavior to recursively check for deduplication of names (and thus avoid an error) (#76)

* Add named support for the `NSE` versions of dplyr functions (`filter()`,`mutate()`,`slice()`, etc.) since the `SE` variants are no longer called behind-the-scenes since `dplyr 0.6.0`. (#97)

* Fix errors with `print.tbl_json()` when the JSON attribute is missing

* Fix json_structure() failure if `document.id` missing by imputing
the missing `document.id`. (#86)

## Deprecated functions

* `jstring()`, `jnumber()`, `jlogical()` -> use `json_chr()`, `json_dbl()`, `json_lgl()` instead (#93)

* `is_json_string()`,`is_json_number()`,`is_json_logical()` -> use `is_json_chr()`, `is_json_dbl()`, `is_json_lgl()` instead (#93)

* `append_values_string()`, `append_values_number()`, `append_values_logical()` -> use `append_chr()`, `append_dbl()`, `append_lgl()` instead (#93)

# tidyjson 0.2.1.9000

## New functions

Expand Down
43 changes: 32 additions & 11 deletions R/append_values.R
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#'
#' Any values that can not be converted to the specified will be \code{NA} in
#' the resulting column. This includes other scalar types (e.g., numbers or
#' logicals if you are using \code{append_values_string}) and *also* any rows
#' logicals if you are using \code{append_chr}) and *also* any rows
#' where the JSON is NULL or an object or array.
#'
#' Note that the \code{append_values} functions do not alter the JSON
Expand All @@ -30,17 +30,17 @@
#' # Stack names
#' '{"first": "bob", "last": "jones"}' %>%
#' gather_object %>%
#' append_values_string
#' append_chr
#'
#' # This is most useful when data is stored in name-value pairs
#' # For example, tags in recipes:
#' recipes <- c('{"name": "pie", "tags": {"apple": 10, "pie": 2, "flour": 5}}',
#' '{"name": "cookie", "tags": {"chocolate": 2, "cookie": 1}}')
#' recipes %>%
#' spread_values(name = jstring(name)) %>%
#' spread_values(name = json_chr(name)) %>%
#' enter_object(tags) %>%
#' gather_object("tag") %>%
#' append_values_number("count")
#' append_dbl("count")
NULL

#' Creates the append_values_* functions
Expand All @@ -52,12 +52,12 @@ append_values_factory <- function(type, as.value) {

if (!is.tbl_json(.x)) .x <- as.tbl_json(.x)

if (force == FALSE) assert_that(recursive == FALSE)
if (force == FALSE) assertthat::assert_that(recursive == FALSE)

# Extract json
json <- attr(.x, "JSON")

assert_that(length(json) == nrow(.x))
assertthat::assert_that(length(json) == nrow(.x))

# if json is empty, return empty
if (length(json) == 0) {
Expand All @@ -78,7 +78,7 @@ append_values_factory <- function(type, as.value) {
new_val[loc] <- NA
}
new_val <- new_val %>% as.value
assert_that(length(new_val) == nrow(.x))
assertthat::assert_that(length(new_val) == nrow(.x))
.x[column.name] <- new_val
}

Expand All @@ -92,7 +92,7 @@ append_values_factory <- function(type, as.value) {
#' @param l a list that we want to unlist
#' @param recursive logical indicating whether to unlist nested lists
my_unlist <- function(l, recursive = FALSE) {
nulls <- map_int(l, length) != 1
nulls <- purrr::map_int(l, length) != 1
l[nulls] <- NA
unlist(l, recursive = recursive)
}
Expand Down Expand Up @@ -120,12 +120,33 @@ append_values_type <- function(json, type) {

#' @export
#' @rdname append_values
append_values_string <- append_values_factory("string", as.character)
append_chr <- append_values_factory("string", as.character)

#' @export
#' @rdname append_values
append_values_number <- append_values_factory("number", as.numeric)
append_values_string <- function(.x, column.name = 'string', force = TRUE, recursive = FALSE){
.Deprecated(new='append_chr')
append_chr(.x,column.name,force,recursive)
}

#' @export
#' @rdname append_values
append_dbl <- append_values_factory("number", as.numeric)

#' @export
#' @rdname append_values
append_values_number <- function(.x, column.name = 'number', force = TRUE, recursive = FALSE){
.Deprecated(new='append_dbl')
append_dbl(.x,column.name,force,recursive)
}

#' @export
#' @rdname append_values
append_lgl <- append_values_factory("logical", as.logical)

#' @export
#' @rdname append_values
append_values_logical <- append_values_factory("logical", as.logical)
append_values_logical <- function(.x, column.name = 'logical', force = TRUE, recursive = FALSE){
.Deprecated(new='append_lgl')
append_lgl(.x,column.name,force,recursive)
}
2 changes: 1 addition & 1 deletion R/data-issues.R
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
#' # Count issues labels by name
#' labels <- issues %>%
#' gather_array %>% # stack issues as "issue.num"
#' spread_values(id = jnumber(id)) %>% # capture just issue id
#' spread_values(id = json_dbl(id)) %>% # capture just issue id
#' enter_object(labels) %>% # filter just those with labels
#' gather_array("label.index") %>% # stack labels
#' spread_all
Expand Down
2 changes: 1 addition & 1 deletion R/data-worldbank.R
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
#' select(project_name, regionname) %>%
#' enter_object(majorsector_percent) %>% # Enter the 'sector' object
#' gather_array("sector.index") %>% # Gather the array
#' spread_values(sector = jstring(Name)) # Spread the sector name
#' spread_values(sector = json_chr(Name)) # Spread the sector name
#'
#' # Examine the structured data
#' wb_sectors %>% glimpse
Expand Down
8 changes: 4 additions & 4 deletions R/enter_object.R
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
#'
#' @seealso \code{\link{gather_object}} to find sub-objects that could be
#' entered into, \code{\link{gather_array}} to gather an array in an object
#' and \code{\link{spread_all}} to spread values in an object.
#' and \code{\link{spread_all}} or \code{\link{spread_values}} to spread values in an object.
#' @param .x a json string or tbl_json object
#' @param ... a quoted or unquoted sequence of strings designating the object
#' name or sequences of names you wish to enter
Expand Down Expand Up @@ -44,10 +44,10 @@
#' json %>% spread_all %>% enter_object(children) %>%
#' gather_array("child.num")
#'
#' # And append_values_string to add the children names
#' # And append_chr to add the children names
#' json %>% spread_all %>% enter_object(children) %>%
#' gather_array("child.num") %>%
#' append_values_string("child")
#' append_chr("child")
#'
#' # The path can be comma delimited to go deep into a nested object
#' json <- '{"name": "bob", "attributes": {"age": 32, "gender": "male"}}'
Expand All @@ -71,7 +71,7 @@ enter_object <- function(.x, ...) {
json <- attr(.x, "JSON")

# Access path
json <- map(json, path %>% as.list)
json <- purrr::map(json, path %>% as.list)

tbl_json(.x, json, drop.null.json = TRUE)

Expand Down
28 changes: 14 additions & 14 deletions R/gather.R
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ gather_factory <- function(default.column.name, default.column.empty,

function(.x, column.name = default.column.name) {

assert_that(!("..name" %in% names(.x)))
assert_that(!("..json" %in% names(.x)))
assertthat::assert_that(!("..name" %in% names(.x)))
assertthat::assert_that(!("..json" %in% names(.x)))

if (!is.tbl_json(.x)) .x <- as.tbl_json(.x)

Expand All @@ -36,13 +36,13 @@ gather_factory <- function(default.column.name, default.column.empty,
stop(sprintf("%s records are not %ss", sum(bad_type), required.type))

y <- .x %>%
tbl_df %>%
mutate(
..name = json %>% map(expand.fun),
dplyr::as_tibble() %>%
dplyr::mutate(
..name = json %>% purrr::map(expand.fun),
..json = json %>%
map(~data_frame(..json = as.list(.)))
purrr::map(~dplyr::data_frame(..json = as.list(.)))
) %>%
unnest(..name, ..json, .drop = FALSE)
tidyr::unnest(..name, ..json, .drop = FALSE)

# Check to see if column.name exists, otherwise, increment until not
if (column.name %in% names(y)) {
Expand All @@ -58,10 +58,10 @@ gather_factory <- function(default.column.name, default.column.empty,
}

# Rename
y <- y %>% rename_(.dots = setNames("..name", column.name))
y <- y %>% dplyr::rename_(.dots = setNames("..name", column.name))

# Construct tbl_json
tbl_json(y %>% select(-..json), y$..json)
tbl_json(y %>% dplyr::select(-..json), y$..json)

}

Expand Down Expand Up @@ -107,14 +107,14 @@ gather_factory <- function(default.column.name, default.column.empty,
#' # Then we can use the column.name argument to change the column name
#' json %>% gather_object("year")
#'
#' # We can also use append_values_number to capture the values, since they are
#' # We can also use append_dbl to capture the values, since they are
#' # all of the same type
#' json %>% gather_object("year") %>% append_values_number("count")
#' json %>% gather_object("year") %>% append_dbl("count")
#'
#' # This can even work with a more complex, nested example
#' json <- '{"2015": {"1": 10, "3": 1, "11": 5}, "2016": {"2": 3, "5": 15}}'
#' json %>% gather_object("year") %>% gather_object("month") %>%
#' append_values_number("count")
#' append_dbl("count")
#'
#' # Most JSON starts out as an object (or an array of objects), and
#' # gather_object can be used to inspect the top level (or 2nd level) objects
Expand Down Expand Up @@ -173,7 +173,7 @@ gather_keys <- function(.x, column.name = "key") {
#' json %>% gather_array %>% json_types
#'
#' # Extract string values
#' json %>% gather_array %>% append_values_string
#' json %>% gather_array %>% append_chr
#'
#' # A more complex mixed type example
#' json <- '["a", 1, true, null, {"name": "value"}]'
Expand All @@ -186,7 +186,7 @@ gather_keys <- function(.x, column.name = "key") {
#'
#' # Extract both levels
#' json %>% gather_array("index.1") %>% gather_array("index.2") %>%
#' append_values_string
#' append_chr
#'
#' # Some JSON begins as an array
#' commits %>% gather_array
Expand Down
Loading

0 comments on commit 168b4d7

Please sign in to comment.