`Pipe`

object supports direct subsetting using `[]`

, element extraction using `[[]]`

, and element assignment using `<-`

. The operation is done with the value in `Pipe`

rather than `Pipe`

itself.

`[]`

Traditionally, `[]`

is used to subset a vector or list. `Pipe`

object implements `[]`

too so that you can directly subset the inner value without breaking the `Pipe`

.

```
Pipe(list(a=1,b=2,c=3))[c("a","b")]
```

```
# <Pipe: list>
# $a
# [1] 1
#
# $b
# [1] 2
```

```
Pipe(mtcars)[c("mpg","cyl","wt")]$
head()
```

```
# <Pipe: data.frame>
# mpg cyl wt
# Mazda RX4 21.0 6 2.620
# Mazda RX4 Wag 21.0 6 2.875
# Datsun 710 22.8 4 2.320
# Hornet 4 Drive 21.4 6 3.215
# Hornet Sportabout 18.7 8 3.440
# Valiant 18.1 6 3.460
```

Note that the value after subsetting is still a `Pipe`

containing the subsetted value to allow further piping.

In fact, it does not only supports simple subsetting operations on vectors and lists, it also supports complex and highly customized subsetting such as subsetting a `data.table`

.

```
library(data.table)
set.seed(0)
dt <- data.table(id = 1:6, x = rnorm(6), y = rep(letters[1:3]), key = "id")
dt
```

```
# id x y
# 1: 1 1.2629543 a
# 2: 2 -0.3262334 b
# 3: 3 1.3297993 c
# 4: 4 1.2724293 a
# 5: 5 0.4146414 b
# 6: 6 -1.5399500 c
```

```
Pipe(dt)[1:3] # select by row index
```

```
# <Pipe: data.table data.frame>
# id x y
# 1: 1 1.2629543 a
# 2: 2 -0.3262334 b
# 3: 3 1.3297993 c
# 4: 4 1.2724293 a
# 5: 5 0.4146414 b
# 6: 6 -1.5399500 c
```

```
Pipe(dt)[J(3)] # join by key
```

```
# Error in `[.data.frame`(x, i): could not find function "J"
```

```
Pipe(dt)[, sum(x), by = list(y)] # group sum
```

```
# Error in `[.data.frame`(x, i, j): object 'x' not found
```

```
Pipe(dt)[, z := x^2+1] # reference mutate
```

```
# Error in `:=`(z, x^2 + 1): Check that is.data.table(DT) == TRUE. Otherwise, := and `:=`(...) are defined for use in j, once only and in particular ways. See help(":=").
```

The important thing here is that using `Pipe()`

you can enjoy smooth piping experience and don't have to worry interruptions by subsetting like them. Therefore, you can enjoy the smoking performance of `data.table`

with pipeline operations even though it is not by designed pipe-friendly.

For example, first we convert `mtcars`

to `data.table`

and put its row names into a new columns called `name`

which is set as key. Since the output is a `Pipe`

object containing the `data.table`

, we name it `pmtcars`

to remind ourselves it is a `Pipe`

rather than an ordinary object.

```
pmtcars <- Pipe(mtcars)$
.(~ rownames(.) -> row_names)$
as.data.table()[, name := row_names]$
setkey(name)
```

```
# Error in `:=`(name, row_names): Check that is.data.table(DT) == TRUE. Otherwise, := and `:=`(...) are defined for use in j, once only and in particular ways. See help(":=").
```

We can subset it with `[]`

as we showed. Remember, being a `Pipe`

object means we can use `$`

to pipe its inner value forward.

```
pmtcars[mpg >= quantile(mpg,0.05)]$
lm(formula = mpg ~ wt + cyl)$
summary()$
coef()
```

```
# Error in `[.data.frame`(., mpg >= quantile(mpg, 0.05)): object 'mpg' not found
```

One thing to notice is that `[]`

is evaluated with `.`

representing the value in `Pipe`

, which makes it easier to use by avoiding redundant references to the value many times.

Traditionally, if we want to move out the last entry from a vector, we have to somehow compute its length.

```
mtcars$mpg[-length(mtcars$mpg)]
```

```
# [1] 21.0 21.0 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 17.8 16.4 17.3 15.2
# [15] 10.4 10.4 14.7 32.4 30.4 33.9 21.5 15.5 15.2 13.3 19.2 27.3 26.0 30.4
# [29] 15.8 19.7 15.0
```

Using `Pipe()`

the code can be rewritten as

```
Pipe(mtcars$mpg)[-length(.)]
```

```
# <Pipe: numeric>
# [1] 21.0 21.0 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 17.8 16.4 17.3 15.2
# [15] 10.4 10.4 14.7 32.4 30.4 33.9 21.5 15.5 15.2 13.3 19.2 27.3 26.0 30.4
# [29] 15.8 19.7 15.0
```

`[[]]`

Just like `[]`

, `[[]]`

also behaves according to the same design logic. It extracts an element from vector, list, and environment.

```
Pipe(mtcars)[["mpg"]]$
summary()
```

```
# <Pipe: summaryDefault table>
# Min. 1st Qu. Median Mean 3rd Qu. Max.
# 10.40 15.42 19.20 20.09 22.80 33.90
```

If you prefer not to use element extraction like this, there are various alternative ways to do exactly the same thing.

```
# work with vector, list, environment, S4 objects.
Pipe(mtcars)$
.(mpg)$
summary()
# work with list, environment.
Pipe(mtcars)$
.(summary(.$mpg))
# work with list, environment.
Pipe(mtcars)$
with(summary(mpg))
```

All the above work and do the same thing. In practice, different approaches may result in different degrees of readability. You have to choose by your preference.

In addition to subsetting and extracting, `Pipe`

object also supports element assignment including element assignment (`$<-`

and `[[<-`

) and subset assignment (`[<-`

).

```
lst <- Pipe(list(a=1,b=2))
lst
```

```
# <Pipe: list>
# $a
# [1] 1
#
# $b
# [1] 2
```

```
lst$a <- 2
lst
```

```
# <Pipe: list>
# $a
# [1] 2
#
# $b
# [1] 2
```

```
lst[["b"]] <- NULL
lst
```

```
# <Pipe: list>
# $a
# [1] 2
```

```
lst$c <- 1:3
lst
```

```
# <Pipe: list>
# $a
# [1] 2
#
# $c
# [1] 1 2 3
```

```
lst[c("a","c")] <- list(1:3, 2:5)
lst
```

```
# <Pipe: list>
# $a
# [1] 1 2 3
#
# $c
# [1] 2 3 4 5
```