Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Devel #117

Merged
merged 4 commits into from
Jun 29, 2018
Merged

Devel #117

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@
^xtable_vs_pixiedust.html$
^xtable_vs_pixiedust.Rmd$
^\inst\save_sprinkles_rda.R$
^\revdep\*
^revdep$
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: pixiedust
Title: Tables so Beautifully Fine-Tuned You Will Believe It's Magic
Version: 0.8.3
Version: 0.8.4
Authors@R: c(person("Benjamin", "Nutter", email = "[email protected]", role = c("aut", "cre")),
person("David", "Kretch", role = c("ctb")))
Description: The introduction of the 'broom' package has made converting model
Expand Down
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ export("%<>%")
export("%>%")
export(dust)
export(fixed_header_css)
export(gaze)
export(get_dust_part)
export(get_pixie_count)
export(increment_pixie_count)
Expand Down
5 changes: 5 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
### 0.8.4 (2018-06-29)

* Added `gaze` function to produce model summaries side-by-side (#80)
* Small adjustments to work with upcoming version of `broom`.

### 0.8.3 (2018-03-22)

* Repaired recycling in several sprinkles. Sprinkles that permit more than
Expand Down
174 changes: 174 additions & 0 deletions R/gaze.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
#' @name gaze
#' @title Mimic Stargazer Output to Display Multiple Models
#'
#' @description Tidy multiple models and display coefficients and
#' test statistics in a side-by-side format.
#'
#' @param ... models to be tidied. Arguments may be named or unnamed.
#' For named arguments, the model will be identfied by the argument
#' name; for unnamed arguments, the object name will be the identifier.
#' @param include_glance \code{logical(1)} Determines if \code{glance} (fit)
#' statistics are displayed under the models.
#' @param glance_vars \code{character}. A vector of statistics returned by
#' \code{glance} that are to be displayed for each model. Defaults are
#' subject to change in future versions.
#' @param digits \code{numeric(1)} The number of digits used for rounding.
#'
#' @details This function is still in development. Significant stars
#' will be added in a future version. Note that function defaults may
#' be subject to change.
#'
#' @section Functional Requirements:
#' \enumerate{
#' \item Return a data frame object
#' \item Cast an error if \code{include_glance} is not \code{logical(1)}
#' \item Cast an error if \code{glance_vars} is not a \code{character}
#' vector.
#' \item Cast an error if \code{digits} is not \code{"integerish(1)"}.
#' }
#'
#' @examples
#' fit1 <- lm(mpg ~ qsec + am + wt + gear + factor(vs), data = mtcars)
#' fit2 <- lm(mpg ~ am + wt + gear + factor(vs), data = mtcars)
#'
#' gaze(fit1, fit2)
#' gaze(with_qsec = fit1,
#' without_qsec = fit2)
#' gaze(fit1, fit2, include_glance = FALSE)
#' gaze(fit1, fit2, glance_vars = c("AIC", "BIC"))
#'
#' @export

gaze <- function(..., include_glance = TRUE,
glance_vars = c("adj.r.squared", "sigma", "AIC"),
digits = 3){

coll <- checkmate::makeAssertCollection()

checkmate::assert_logical(x = include_glance,
len = 1,
add = coll)

checkmate::assert_character(x = glance_vars,
add = coll)

checkmate::assert_integerish(x = digits,
len = 1,
add = 1)

checkmate::reportAssertions(coll)

fits <- list(...)
if (is.null(names(fits))) names(fits) <- character(length(fits))

# If a fit isn't named, use the object name
dots <- match.call(expand.dots = FALSE)$...
fit_names <- vapply(dots, deparse, character(1))
names(fits)[names(fits) == ""] <- fit_names[names(fits) == ""]

res <- prep_gaze_tidy(fits, names(fits), digits)
if (include_glance){
res <- rbind(res,
prep_gaze_glance(fits, names(fits), glance_vars, digits))
}
res
}


# UNEXPORTED METHODS ------------------------------------------------

prep_gaze_tidy <- function(fits, fit_names, digits){
res <-
mapply(
FUN =
function(fit, name)
{
data.frame(model = name,
broom::tidy(fit),
stringsAsFactors = FALSE)
},
fit = fits,
name = fit_names,
SIMPLIFY = FALSE
)

res <- dplyr::bind_rows(res)

res <- res[c("model", "term", "estimate", "statistic")]
res[["term"]] <- factor(res[["term"]],
levels = unique(res[["term"]]))

res <-
stats::reshape(
data = res,
direction = "long",
varying = list(value = c("estimate", "statistic")),
v.names = "value",
timevar = "variable",
times = c("estimate", "statistic")
)

rownames(res) <- NULL

res[["value"]] <- round(res[["value"]], digits)
statistic_row <- res[["variable"]] == "statistic"
res[["value"]][statistic_row] <-
sprintf("(%s)",
res[["value"]][statistic_row])

res <-
stats::reshape(
data = res[!names(res) %in% "id"],
direction = "wide",
v.names = "value",
idvar = c("term", "variable"),
timevar = c("model"))

res <- res[order(res[["term"]], res[["variable"]]), ]
names(res) <- sub("^value\\.", "", names(res))
res[!names(res) %in% "variable"]
}


prep_gaze_glance <- function(fits, fit_names, glance_vars, digits){
res <-
mapply(
FUN =
function(fit, name)
{
data.frame(model = name,
broom::glance(fit),
stringsAsFactors = FALSE)
},
fit = fits,
name = fit_names,
SIMPLIFY = FALSE
)

res <- dplyr::bind_rows(res)
res <- res[c("model", glance_vars)]

res <-
stats::reshape(
data = res,
direction = "long",
times = glance_vars,
varying = list(value = glance_vars)
)

names(res)[2:3] <- c("term", "value")
res[["value"]] <- round(res[["value"]], digits)


res <-
stats::reshape(
data = res[!names(res) %in% "id"],
direction = "wide",
v.names = "value",
idvar = c("term"),
timevar = c("model"))

names(res) <- sub("^value\\.", "", names(res))
rownames(res) <- NULL
res
}
4 changes: 3 additions & 1 deletion R/glance_foot.R
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,9 @@ glance_foot <- function(fit, col_pairs, total_cols,

checkmate::reportAssertions(coll)

g <- broom::tidy(t(g[glance_stats]))
g <- data.frame(.rownames = names(g[glance_stats]),
unrowname.x. = unname(unlist(g[glance_stats][1, ])),
stringsAsFactors = FALSE)
# return(g)
if (nrow(g) %% col_pairs > 0){
n_fill <- (col_pairs - nrow(g) %% col_pairs)
Expand Down
13 changes: 9 additions & 4 deletions cran-comments.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
## Test environments
* local Linux install (R-3.4.3; #135-Ubuntu SMP Fri Jan 19 11:48:36 UTC 2018)
* remote Linux install (R-3.4.2; ubuntu 4.8.4-2ubuntu1~14.04.3)
* local Linux install (R-3.4.4; #135-Ubuntu SMP Fri Jan 19 11:48:36 UTC 2018)
* remote Linux install (R-3.5.0; Ubuntu 14.04.5 LTS, Travis CI)
* local Windows install (R 3.5.0)
* win-builder (release R 3.5.0)
* win-builder (2018-05-05 r74699)
* win-builder (2018-06-26 r74934)

## R CMD check results
This update corrects one of the tests related to a change in how errors are reported from the `checkmate` package.
This update adjusts for changes coming with a pending update to the `broom`
package.

There were no warnings, errors, or notes returned by CHECK on any of the
test environments.


## Downstream dependencies
Expand Down
54 changes: 54 additions & 0 deletions man/gaze.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion tests/testthat/test-dust.R
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,12 @@ test_that("dust runs when passed a data frame with tidy_df = FALSE",

test_that("dust runs when passed a data frame with tidy_df = TRUE",
{
expect_silent(dust(mtcars, tidy_df = TRUE))
# 25 Jun 2018 Changed to expect warning since broom is deprecating data frame
# tidiers
if (utils::compareVersion(as.character(packageVersion("broom")), "0.4.4") == 1)
expect_warning(dust(mtcars, tidy_df = TRUE))
else
expect_silent(dust(mtcars, tidy_df = TRUE))
})

test_that("dust with keep_rownames = TRUE adds rownames to object",
Expand Down
69 changes: 69 additions & 0 deletions tests/testthat/test-gaze.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
context("gaze.R")

fit1 <- lm(mpg ~ qsec + wt + factor(gear),
data = mtcars)

fit2 <- lm(mpg ~ disp + qsec + wt + factor(gear),
data = mtcars)

# Functional Requirement 1 ------------------------------------------

test_that(
"Return a data frame object",
{
checkmate::expect_data_frame(
gaze(fit1, fit2)
)
}
)

# Functional Requirement 2 ------------------------------------------

test_that(
"Cast an error if include_glance is not logical(1)",
{
expect_error(
gaze(fit1, fit2, include_gaze = "yes")
)
}
)

test_that(
"Cast an error if include_glance is not logical(1)",
{
expect_error(
gaze(fit1, fit2, include_gaze = c(TRUE, FALSE))
)
}
)

# Functional Requirement 3 ------------------------------------------

test_that(
"Cast an error if glance_vars is not a character vector.",
{
expect_error(
gaze(fit1, fit2, glance_vars = list(1:3, letters))
)
}
)

# Functional Requirement 4 ------------------------------------------

test_that(
"Cast an error if digits is not integerish(1)",
{
expect_error(
gaze(fit1, fit2, digits = "two")
)
}
)

test_that(
"Cast an error if digits is not integerish(1)",
{
expect_error(
gaze(fit1, fit2, digits = c(2, 3))
)
}
)
4 changes: 2 additions & 2 deletions tests/testthat/test-perform_function.R
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ test_that("Apply a calculation",

x <- perform_function(x$body)

expect_equal(x[x$row == 2 & x$col %in% 2:3, "value"],
expect_equal(x$value[x$row == 2 & x$col %in% 2:3],
c("-1.24", "-0.38"))
})

Expand All @@ -20,6 +20,6 @@ test_that("Apply a string manipulation",

x <- perform_function(x$body)

expect_equal(x[x$row %in% 5:6 & x$col == 1, "value"],
expect_equal(x$value[x$row %in% 5:6 & x$col == 1],
c("Gears: 4", "Gears: 5"))
})
Loading