Code Monkey home page Code Monkey logo

Comments (1)

grantmcdermott avatar grantmcdermott commented on May 22, 2024

I'm sure you've already considered this, but a simple proof-of-concept using stack():

pivot_longer = 
  function(
    data,
    cols,
    names_to = "name",
    names_prefix = NULL,
    # names_sep = NULL,
    # names_pattern = NULL,
    # names_ptypes = list(),
    # names_transform = list(),
    # names_repair = "check_unique",
    values_to = "value",
    # values_drop_na = FALSE,
    # values_ptypes = list(),
    # values_transform = list(),
    ...
  ){
    cols = deparse(substitute(cols))
    if (grepl("^!|^-", cols)) {
      cols = setdiff(names(data), gsub("^!|^-", "", cols))
    }
    ocols = setdiff(names(data), cols)
    stacked_data = stack(data[, cols])[, 2:1]
    ret = cbind(data[, ocols], setNames(stacked_data, c(names_to, values_to)))
    if (!is.null(names_prefix)) {
      ret[[names_to]] = gsub(paste0("^", names_prefix), "", ret[[names_to]])
    }
    ret = ret[order(ret[, ocols[1]]), ]
    rownames(ret) = 1:nrow(ret)
    ret
  }

#
## First example from ?tidy::pivot_longer
#

data('relig_income', package = 'tidyr')

## This version
relig_income |>
  pivot_longer(!religion, names_to = "income", values_to = "count") |>
  head(10)
#>    religion             income count
#> 1  Agnostic              <$10k    27
#> 2  Agnostic            $10-20k    34
#> 3  Agnostic            $20-30k    60
#> 4  Agnostic            $30-40k    81
#> 5  Agnostic            $40-50k    76
#> 6  Agnostic            $50-75k   137
#> 7  Agnostic           $75-100k   122
#> 8  Agnostic          $100-150k   109
#> 9  Agnostic              >150k    84
#> 10 Agnostic Don't know/refused    96

## tidyr version
relig_income |>
  tidyr::pivot_longer(!religion, names_to = "income", values_to = "count") |>
  data.frame() |> head(10)
#>    religion             income count
#> 1  Agnostic              <$10k    27
#> 2  Agnostic            $10-20k    34
#> 3  Agnostic            $20-30k    60
#> 4  Agnostic            $30-40k    81
#> 5  Agnostic            $40-50k    76
#> 6  Agnostic            $50-75k   137
#> 7  Agnostic           $75-100k   122
#> 8  Agnostic          $100-150k   109
#> 9  Agnostic              >150k    84
#> 10 Agnostic Don't know/refused    96

#
## Contrived names_prefix useage
#

## This version
relig_income[, c(1, 3:9)] |>
  pivot_longer(!religion, names_to = "income", values_to = "count", names_prefix = "\\$") |>
  head(10)
#>    religion   income count
#> 1  Agnostic   10-20k    34
#> 2  Agnostic   20-30k    60
#> 3  Agnostic   30-40k    81
#> 4  Agnostic   40-50k    76
#> 5  Agnostic   50-75k   137
#> 6  Agnostic  75-100k   122
#> 7  Agnostic 100-150k   109
#> 8   Atheist   10-20k    27
#> 9   Atheist   20-30k    37
#> 10  Atheist   30-40k    52

## tidyr version
relig_income[, c(1, 3:9)] |>
  tidyr::pivot_longer(!religion, names_to = "income", values_to = "count", names_prefix = "\\$") |>
  data.frame() |> head(10)
#>    religion   income count
#> 1  Agnostic   10-20k    34
#> 2  Agnostic   20-30k    60
#> 3  Agnostic   30-40k    81
#> 4  Agnostic   40-50k    76
#> 5  Agnostic   50-75k   137
#> 6  Agnostic  75-100k   122
#> 7  Agnostic 100-150k   109
#> 8   Atheist   10-20k    27
#> 9   Atheist   20-30k    37
#> 10  Atheist   30-40k    52

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

Two asides:

  1. I have a strong suspicion that going with stack/unstack is ultimately going to be easier than reshape. The latter is (a) very particular about its input form and arguments, and (b) you'll probably end up having to do some binds and internal manipulation anyway once you start invoking the additional pivot_* arguments.
  2. The main complication for extending this proof of concept is handling the NSE. But I believe(?) you've already developed an internal system for deparsing NSE vectors etc. So, that could make things a lot easier.

EDIT: Added names_prefix arg and example.

from poorman.

Related Issues (20)

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.