Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Base Analogue of `arrange()` in Pipelines

Tags:

dataframe

r

dplyr

Pipelines using dplyr::filter() and dplyr::mutate() can often be replaced with base-R equivalents subset() and transform(), a possible benefit in package development. Is there any direct base-R analogue of arrange() that can used in a base-R pipeline?

Of course there is order(), but usage in a pipeline is not as clear as arrange(). Below is the best I came up with, but it's not lovely:

set.seed(0)
dat <- data.frame(x = 1:5, y = sample(100, 5))
dat

library(dplyr)
dat |> 
  filter(x > 2) |> 
  mutate(z = y / x) |> 
  arrange(z)

# Using base-R only
dat |> 
  subset(x > 2) |> 
  transform(z = y / x) |> 
  {\(d) d[order(d$z), ]}()

Result:

  x  y     z
4 4  1  0.25
5 5 34  6.80
3 3 39 13.00
like image 558
nahp Avatar asked Sep 02 '25 02:09

nahp


1 Answers

I don't think that there is a good base equivalent to dplyr::arrange(). We could write our own function which would behave similar to substitute(), lets call it organize():

set.seed(0)
dat <- data.frame(x = 1:5, y = sample(100, 5))

organize <- function (df, ..., na.last = TRUE, decreasing = FALSE,
                      method = c("auto", "shell", "radix"), drop = FALSE) {
  method <- match.arg(method)
  dots <- eval(substitute(alist(...)))
  exprs <- lapply(dots, FUN = \(e) eval(e, df, parent.frame())) 
  arg_ls <- c(exprs,
              na.last = na.last,
              decreasing = decreasing,
              method = method
              )
  df[do.call("order", arg_ls), , drop = drop]
}

dat |>
  subset(select = 2) |>
  organize(y)
#>    y
#> 4  1
#> 1 14
#> 5 34
#> 3 39
#> 2 68

mtcars |>
  organize(gear, -mpg) |>
  head()
#>                    mpg cyl  disp  hp drat    wt  qsec vs am gear carb
#> Toyota Corona     21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1
#> Hornet 4 Drive    21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
#> Pontiac Firebird  19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2
#> Hornet Sportabout 18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
#> Valiant           18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
#> Merc 450SL        17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3

Created on 2023-03-08 with reprex v2.0.2

like image 124
TimTeaFan Avatar answered Sep 06 '25 13:09

TimTeaFan