Git Product home page Git Product logo

ggcheck's Introduction

RStudio

RStudio is an integrated development environment (IDE) for the R programming language. Some of its features include:

  • Customizable workbench with all of the tools required to work with R in one place (console, source, plots, workspace, help, history, etc.).
  • Syntax highlighting editor with code completion.
  • Execute code directly from the source editor (line, selection, or file).
  • Full support for authoring Sweave and TeX documents.
  • Runs on Windows, Mac, and Linux, and has a community-maintained FreeBSD port.
  • Can also be run as a server, enabling multiple users to access the RStudio IDE using a web browser.

For more information on RStudio please visit the project website.

Getting the Code

RStudio is licensed under the AGPLv3, the terms of which are included in the file COPYING. You can find our source code repository on GitHub at https://github.com/rstudio/rstudio.

Documentation

For information on how to use RStudio check out our online documentation.

For documentation on running your own RStudio Server see the server getting started guide.

See also the following files included with the distribution:

  • COPYING - RStudio license (AGPLv3)
  • NOTICE - Additional open source software included with RStudio
  • SOURCE - How to obtain the source code for RStudio
  • INSTALL - How to build and install RStudio from source

If you have problems or want to share feedback with us please visit our community forum. For other inquiries you can also email us at [email protected].

ggcheck's People

Contributors

gadenbuie avatar garrettgman avatar github-actions[bot] avatar nischalshrestha avatar rossellhayes avatar skaltman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ggcheck's Issues

Check facets

At a minimum, we want to check for:

  • the functions (e.g. facet_wrap vs facet_grid)
  • the variables within the functions (e.g. ~ cyl or drv ~ cyl or nrow = 1)

Check themes

This is arguable the "wild west" of ggplot2, so we can start simple by checking that code uses of one of the complete themes (e.g. theme_bw vs theme_classic). We can then expand later to individual element via theme().

Get and check aes params

It would be useful to be able to check for aesthetic parameters (i.e., aesthetics that have been set and not mapped), such as fill = "blue":

library(ggcheck)
library(ggplot2)

p <-
  ggplot(mpg, aes(manufacturer)) +
  geom_bar(fill = "blue", width = 0.5)

Created on 2021-11-16 by the reprex package (v2.0.1)

uses_geom_param() checks "geom params", (binwidth, etc.), but not "aes params" (fill = "blue"):

uses_geom_param(p, "bar", params = list(fill = "blue"))
#> Error in uses_geom_param(p, "bar", params = list(fill = "blue")): Grading error: the supplied parameters 'fill' are invalid.
uses_geom_param(p, "bar", params = list(width = 0.5))
#> [1] TRUE

It would also be nice to be able to easily get aes params. You can do:

get_geom_layer(p, geom = "bar")$layer$aes_params
#> $fill
#> [1] "blue"

but it would be nice to have a function.

Check a layer's parameters

We would like to be able to check the values of parameters or somehow introspect the layer's params. For e.g. the geom_hist accepts a binwidth , and we'd like to check that they are using the correct value there. Another example is checking if a geom_boxplot is using a specific outlier.alpha (e.g. 0.01).

We would also like to be able check a layer created using a stat_ function, for example the stat_bin for creating a geom_bar where we can also grade the parameters like bins.

`uses_mappings()` doesn't distinguish between strings and variables

uses_mappings() doesn't distinguish between a variable being mapped to an aesthetic and the name of the variable (as a string) being mapped:

library(ggplot2)
library(ggcheck)

p <-
  ggplot(mpg, aes(x = cty, y = "hwy")) +
  geom_point()

uses_mappings(p, mappings = aes(x = cty, y = hwy))
#> [1] TRUE

Created on 2021-10-14 by the reprex package (v0.3.0)

get_mappings() captures the distinction:

get_mappings(p)
#> Aesthetic mapping: 
#> * `x` -> `cty`
#> * `y` -> "hwy"

I think the issue is coming from identical_aes(), since it converts all the aesthetic mappings to characters using rlang::as_name().

Check scales

Some things we want to check to start:

  • xlim / ylim
  • x / y labels
  • title / subtitle

Check coordinates

To start, we want to be able to check a couple of things about coordinates axes:

  • the function (e.g. cord_cartesian)
  • the parameters for the function (e.g. xlim/ylim)

Feature request: general `grade_this_plot()` type function

tblcheck::grade_this_table() and its related variants has been a phenomenally useful grading function that has become a go-to function among exercise writers. It performs a thorough comparison between the result of the students code and the result of the solution code, checking the various important ways that two tables can be different.

Can we provide something similar for grading plots?

grade_this_plot() could begin by performing a few rudimentary checks that we know work well. This would allow exercise writers to quickly begin writing code with grade_this_plot(). Over time, we could add more and better checks—and these would automatically be applied to exercises that use grade_this_plot() without the exercise writers needing to revisit the templates (and template tests should keep us from breaking anything as we do).

Handle how a layer's geom and stat are checked

A ggplot layer is composed of a combination of geom and stat recorded in the ggplot object. This is nice for flexibility of creating a layer, but tricky for grading either one or a combination because names are not always mirrored between geoms and stats.

We need a system that maintains the proper default mapping between the two for a type of plot. A lookup table might help:

geom GEOM STAT
"qq" "point" "qq"
"histogram" "bar" "bin"
... ... ...

A utility function can perform the lookup table, which can be used by a uses_geoms or uses_stats function for checking.

The one complication here is that when creating a layer using geom_ function vs creating a layer using stat_ function, the classes of the underlying geom/stat do not necessarily map. A possible workaround is to maintain another column, stat so we can support a stat-centric table when creating layers using stat_ functions.

It might be worth checking out {gradethis} new checking flow to alleviate this problem by simply extracting out each geom/stat ahead of checking code.

Add pattern to check for presence of label in plot

It might be useful to update the uses_label() API to make it easier to test for the presence of user defined labels. Using the example from #22, unnamed arguments would simply be a test for presence of the label, not specifically comparing a value:

library(ggcheck)
library(ggplot2)

p <- ggplot(mtcars, aes(x = wt, y = mpg, color = cyl)) +
  geom_point() +
  labs(x = "weight", y = "MPG", color = NULL)

get_labels(p)
#> $x
#> [1] "weight"
#> 
#> $y
#> [1] "MPG"
#> 
#> $colour
#> NULL
uses_labels(p, "x")
#> [1] TRUE

uses_labels(p, x = "weight")
#> [1] TRUE

uses_labels(p, "fill")
#> [1] FALSE

uses_labels(p, "fill", "shape")
#> [1] FALSE FALSE

cc @brendanhcullen

Add helper to test that the user submitted a ggplot2

library(ggplot2)
library(ggcheck)

When a user misses a + or has another small mistake in the snytax, the last value from running their code can end up being a ggplot2 component (layer, aesthetic, etc) but not the plot we expect.

.result <- local({
  ggplot(mpg) +
    aes(x = hwy, y = cyl) + 
    geom_point() 
    geom_smooth()
})

If you try to use ggcheck functions right away, we run into an error.

uses_data(.result, mpg)
#> Error in UseMethod("get_data"): no applicable method for 'get_data' applied to an object of class "c('LayerInstance', 'Layer', 'ggproto', 'gg')"

We need a helper function to test that the output is a ggplot2 plot and to give useful feedback — did you forget a +, etc. — without giving away the answer via code checking.

inherits(.result, "ggplot")
#> [1] FALSE

Created on 2021-11-05 by the reprex package (v2.0.1)

Add `uses_facet()`

@skaltman built some clever code to check for facets:

get_facet <- function(.result) {
  stringr::str_remove(deparse(.result$facet$params$facets[[1]]), "~")
}

get_facet_params <- function(.result) {
  .result$facet$params
}

ncol <- get_facet_params(.result)$ncol

if (!get_facet(.result) == "plant") {
  fail("Did you remember to facet by `plant` using `facet_wrap()`?")
}

if (is.null(ncol)) {
  fail("I expected you to use the `ncol` argument inside of `facet_wrap()` to match the layout in the example plot.")
}

if (ncol != 2) {
  fail("I expected you to set the number of columns using the `ncol` argument inside of `facet_wrap()`.")
}

We should be able to create similar functions within ggcheck for handling facets.

Rethink functions that take `...`

Having functions that take a list of aesthetics or labels in ... is helpful interactively or when the number of items is small or well known. On the other hand, it's hard to programmatically construct calls to functions like uses_labels() when one is working with an abstract (or unknown) number of labels/aesthetics/etc.

library(ggcheck)
library(ggplot2)

p <- ggplot(mtcars, aes(x = wt, y = mpg, color = cyl)) +
  geom_point() +
  labs(x = "weight", y = "MPG", color = NULL)

The following isn’t possible currently since we need arguments to ..., but we could allow the first argument to be a list, in which case it becomes the starting structure for the internal args list.

uses_labels(p, list(x = "weight", y = "MPG"))
#> Error: All inputs to `...` must be character vectors of length 1 or `NULL`.

Another option is to use rlang’s dynamic dots via rlang::list2() to enable splicing.

uses_labels(p, !!!list(x = "weight", y = "MPG"))
#> Error in !list(x = "weight", y = "MPG"): invalid argument type

Still, the current version calls all() on all of the labels/aesthetics, but from a programmatic perspective it might be better to return a named vector.

uses_labels(p, x = "weight", y = "MPG")
#> [1] TRUE

# may be easier in the long term to return a named logical vector
uses_labels(p, x = "weight", y = "MPG")
#>    x    y
#> TRUE TRUE

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.