Andrie
Andrie

Reputation: 179448

How to extract / subset an element from a list with the magrittr %>% pipe?

Since the introduction of the %>% operator in the magrittr package (and it's use in dplyr), I have started to use this in my own work.

One simple operation has me stumped, however. Specifically, this is the extraction (or subsetting) of elements from a list.

An example: In base R I would use $, [ or [[ to extract an element from a list:

iris$Species
iris[["Species"]]

I can achieve the same using the %>% pipe:

iris %>%
  subset(select = "Species") %>%
  head

  Species
1  setosa
2  setosa
3  setosa
4  setosa
5  setosa
6  setosa

Or

iris %>%
  `[[`("Species") %>%
  levels

[1] "setosa"     "versicolor" "virginica" 

However, this feels like a messy, clunky solution.

Is there a more elegant, canonical way to extract an element from a list using the %>% pipe?

Note: I don't want any solution involving dplyr, for the simple reason that I want the solution to work with any R object, including lists and matrices, not just data frames.

Upvotes: 39

Views: 17756

Answers (3)

iNyar
iNyar

Reputation: 2326

A more recent tidyverse solution: pluck() from purrr (since 0.2.3) extracts a named element from a list (or a named column from a data frame):

library(tidyverse)

iris %>% 
  pluck("Species")

Note: to access the element by index number, you can also use first(), last() or nth() from dplyr on any object (list, data frame, matrix) to extract its first, last or nth element:

iris %>% 
  as.list() %>%  # unnecessary, just to show it works on lists too
  last()         # or nth(5) in this case, to get Species

Upvotes: 9

Bangyou
Bangyou

Reputation: 9816

Use use_series, extract2 and extract for $, [[, [, respectively.

?extract

magrittr provides a series of aliases which can be more pleasant to use when composing chains using the %>% operator."

For your example, you could try

iris %>%
  extract("Species")

and

iris %>%
  extract2("Species") %>%
  levels

See the bottom of this page for more: http://cran.r-project.org/web/packages/magrittr/vignettes/magrittr.html

Upvotes: 39

Stefan
Stefan

Reputation: 1835

In v 1.5 of magrittr on CRAN you can use the %$% operator:

iris %$% 
  Species %>%
  levels

It is essentially a wrapper around with but nicer than

iris %>% 
  with(Species %>% levels)

or

iris %>%
  with(Species) %>%
  levels

It is designed to be convinient when functions don't have their own data argument, e.g. with plot you can do

iris %>% 
  plot(Sepal.Length ~ Sepal.Width, data = .)

but e.g. with ts.plot you can't do that, so now:

iris %$%
  ts.plot(Sepal.Length)

[yeah, I know the example makes no sense, but it illustrates the point]

Note also that [<- and [[<- also have aliases, inset and inset2..

Upvotes: 34

Related Questions