GithubHelp home page GithubHelp logo

huh's Introduction

2022-08-21

Lifecycle: stable Codecov test coverage

Learning R can be hard. R objects can be … how may we put it … intricate? Not only is there is a large variety of objects. That is common for well established programming languages. The issue is rather that sometimes things may look similar but have subtle differences. All in all handling R objects can be quite difficult for a beginner. For newbies it can be quite confusing, even intimidating. I know it was for me.

huh!?

What It Does

The “huh?” package wants to describe objects to make it easier to understand what they are, what they contain and how to handle them. My success measure: How many times do you open the manual? If “huh!?” reduces the number of occasions you start browsing through pages of the manual or your favourite R textbook, in that case this package is a huge success.

It basically offers only two functions:

  1. huh()
  2. how()

… because “Huh!?” must be easy to learn. You do not need to learn many functions and arguments by heart. You simply ask huh(myObject) or how(myObject) in the console and get your result.

huh. huh() describes an object. It gives you the basic type, the class, any attributes including the number of dimensions, and on what paradigm the object is based on. The paradigm tells you whether the object is based on S3, S4, reference or R6 classes.

Example.

library(huh)
# integer vector
huh(1:3)
#> name      : 1:3
#> type      : integer
#> class     : integer
#> dimensions: 1
#> paradigm  : implicit, object

# integer matrix
xy <- matrix(1:4, 2)
huh(xy)
#> name      : xy
#> type      : integer
#> class     : matrix, array
#> dimensions: 2
#> paradigm  : implicit, object

# function (i.e. a closure to be exact)
huh(mean)
#> name    : mean
#> type    : closure
#> class   : function
#> paradigm: S3, generic

how. how() tells you how you can access the contents of an object, which subsetting techniques work, and what the resulting type would be. Also for several objects how() provides further information that is useful when you use the objects.

The output groups subsetting techniques by output type so that it is quite easy what the output of a subsetting operation looks like. A matrix returns an atomic vector when the subset is 1-dimensional unless you add the argument drop=FALSE. But since drop=TRUE is the default how() shows you this:

#> vector 
#> y[c(...)], y[c(...), ...], y[[...]]

The first line is the output type. The second line shows ways to subset the matrix that will return this type. ... means that you can only use a single number or string as index; c(...) allows using a vector of indices.

Example.

library(huh)
# atomic vector
x <- 1:3
how(x)
#> Subsetting 'x'
#> 
#> integer 
#> x[c(...)], x[[...]]

# 2-dimensional access
y <- matrix(1:4, 2)
how(y)
#> Subsetting 'y'
#> 
#> integer 
#> y[c(...)], y[c(...), ...], y[[...]]
#> matrix 
#> y[c(...), c(...)]
#> The result is coerced to the lowest possible dimension. I.e. ... 
#> * 1-dim results yield atomic vectors, 
#> * 2-dim results class 'matrix' 
#> Add the argument `drop=FALSE` to keep the class

# function (...well, a closure to be exact)
how(mean) # not subsettable
#> mean is not subsettable

That is all you need to know.

Installation

You can install the development version of huh from GitHub with:

# install.packages("devtools")
devtools::install_github("SigurdJanson/huh")

Roadmap

The two big steps that are still missing.

  • Improved formatting to enhance readability and bring attention to the essential details of the output.
  • Enhanced ease of use of the output. It should be possible to just copy/paste output to use it.
  • Finish an accompanying vignette about this package and types in R, in general.

Take a look at the issues of the repository if you want to know details.

If you find anything suspicious or you have an idea, just let me know. I am just a regular guy, not an R wizard and I am just trying to be a bit helpful, here. So don’t hesitate if you notice something.

Further Reading

Norberg, R. (2012). Classes and Objects in R. R Bloggers. last access 2022-08-20

huh's People

Contributors

sigurdjanson avatar

Watchers

 avatar

huh's Issues

Do now use expression like `1:3` to illustrate subsetting in `how()`

Because subsetting this 1:3[...] would not make sense. It would have to be (1:3)[...].

So: the idea

  • If the argument x is a symbol, get the name with substitute and use it for the illustration. Also write "name" as label.
  • if the argument x is NOT a symbol, write x. Also use "expression" as label.

If you pass a variable that seems to be a symbol. So, we could check for symbol with typeof(substitute(x)).

local({
  inner <- function(x)
    typeof(substitute(x))
  
  y <- 1
  print(inner(1))
  print(inner(1:2))
  print(inner(y))
  print(inner(expression(a+b)))
})
#> [1] "double"
#> [1] "language"
#> [1] "symbol"
#> [1] "language"

Add formatted output

Possible packages:

  • crayon

  • multicolor

  • cli

  • pillar (only column formatting)

  • cli also seems to support web links.

  • formatOL(x) and formatUL(x) in utils may also be helpful. However, cli would have something similar.

Can subsetting operators from S4 or R6 classes be identified?

"... if how() does not have a specific implementation for an object it looks for the subsetting methods x[], x[[]], and x$. If it finds an implemented method it will show the operator." taken from the vignette.

Does that also work for S4 or R6 classes?

Fix help link for `data.frame`.

The problem does not seem to be me, though:

  • cli::cli_text("{.topic [data frame](base::data.frame)}") does not work, but cli::cli_text("{.topic [data matrix](base::matrix)}") does.
  • cli::cli_text("{.help [data frame](base::data.frame)}") does not work, but cli::cli_text("{.help [data matrix](base::matrix)}") does.

I believe it is a bug. Let's see what this issue will unearth.

CLI does not create the correct output in RMarkdown for HTML output

cli output does not work when creating the Readme. HTML output does not work:

huh(1:3)
#> name : 1:3
#> �]8;;ide:help:base::typeof�type�]8;;�: �]8;;ide:help:base::integer�integer�]8;;�
#> �]8;;ide:help:base::class�class�]8;;�: �]8;;ide:help:base::integer�integer�]8;;�
#> dimensions: 1
#> paradigm : implicit, object

Possible reasons/solutions:

  • let's try checking cli.hyperlink = FALSE. But this may not work. Why? Because I cannot use cli::ansi_has_hyperlink_support() to find out when to set FALSEand when TRUE. Per se HTML does support hyperlinks! See cli::ansi_hyperlink_types()$href.
  • What else can be tried?

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.