The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

Overview

Package provides pipe-style interface for data.table package. It preserves all data.table features without significant impact on performance. let and take functions are simplified interfaces for most common data manipulation tasks.

     mtcars %>%
        let(mpg_hp = mpg/hp) %>%
        take(mean(mpg_hp), by = am)
      mtcars %>%
         let(new_var = 42,
             new_var2 = new_var*hp) %>%
         head()
    iris %>%
      let_all(
          scaled = (.x - mean(.x))/sd(.x),
          by = Species) %>%
       head()
    iris %>%
      take_all(
          mean = if(startsWith(.name, "Sepal")) mean(.x),
          median = if(startsWith(.name, "Petal")) median(.x),
          by = Species
      )
    new_var = "my_var"
    old_var = "mpg"
    mtcars %>%
        let((new_var) := get(old_var)*2) %>%
        head()
     
    # or,  
    expr = quote(mean(cyl))
    mtcars %>% 
        let((new_var) := eval(expr)) %>% 
        head()
    
    # the same with `take` 
    by_var = "vs,am"
    take(mtcars, (new_var) := eval(expr), by = by_var)

query_if function translates its arguments one-to-one to [.data.table method. Additionally there are some conveniences such as automatic data.frame conversion to data.table.

vlookup & xlookup

Let’s make datasets for lookups:

workers = fread("
    name company
    Nick Acme
    John Ajax
    Daniela Ajax
")

positions = fread("
    name position
    John designer
    Daniela engineer
    Cathie manager
")

# xlookup
workers = let(workers,
  position = xlookup(name, positions$name, positions$position)
)

# vlookup
# by default we search in the first column and return values from second column
workers = let(workers,
  position = vlookup(name, positions, no_match = "Not found")
)

# the same 
workers = let(workers,
  position = vlookup(name, positions, 
                     result_column = "position", 
                     no_match = "Not found") # or, result_column = 2 
)

head(workers)
##       name company  position
##     <char>  <char>    <char>
## 1:    Nick    Acme Not found
## 2:    John    Ajax  designer
## 3: Daniela    Ajax  engineer

More examples

We will use for demonstartion well-known mtcars dataset and some examples from dplyr package.

library(maditr)
data(mtcars)

# Newly created variables are available immediately
mtcars %>%
    let(
        cyl2 = cyl * 2,
        cyl4 = cyl2 * 2
    ) %>% head()
##      mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb  cyl2
##    <num> <num> <num> <num> <num> <num> <num> <num> <num> <num> <num> <num>
## 1:  21.0     6   160   110  3.90 2.620 16.46     0     1     4     4    12
## 2:  21.0     6   160   110  3.90 2.875 17.02     0     1     4     4    12
## 3:  22.8     4   108    93  3.85 2.320 18.61     1     1     4     1     8
## 4:  21.4     6   258   110  3.08 3.215 19.44     1     0     3     1    12
## 5:  18.7     8   360   175  3.15 3.440 17.02     0     0     3     2    16
## 6:  18.1     6   225   105  2.76 3.460 20.22     1     0     3     1    12
##     cyl4
##    <num>
## 1:    24
## 2:    24
## 3:    16
## 4:    24
## 5:    32
## 6:    24
# You can also use let() to remove variables and
# modify existing variables
mtcars %>%
    let(
        mpg = NULL,
        disp = disp * 0.0163871 # convert to litres
    ) %>% head()
##      cyl     disp    hp  drat    wt  qsec    vs    am  gear  carb
##    <num>    <num> <num> <num> <num> <num> <num> <num> <num> <num>
## 1:     6 2.621936   110  3.90 2.620 16.46     0     1     4     4
## 2:     6 2.621936   110  3.90 2.875 17.02     0     1     4     4
## 3:     4 1.769807    93  3.85 2.320 18.61     1     1     4     1
## 4:     6 4.227872   110  3.08 3.215 19.44     1     0     3     1
## 5:     8 5.899356   175  3.15 3.440 17.02     0     0     3     2
## 6:     6 3.687098   105  2.76 3.460 20.22     1     0     3     1
# window functions are useful for grouped computations
mtcars %>%
    let(rank = rank(-mpg, ties.method = "min"),
        by = cyl) %>%
    head()
##      mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb  rank
##    <num> <num> <num> <num> <num> <num> <num> <num> <num> <num> <num> <int>
## 1:  21.0     6   160   110  3.90 2.620 16.46     0     1     4     4     2
## 2:  21.0     6   160   110  3.90 2.875 17.02     0     1     4     4     2
## 3:  22.8     4   108    93  3.85 2.320 18.61     1     1     4     1     8
## 4:  21.4     6   258   110  3.08 3.215 19.44     1     0     3     1     1
## 5:  18.7     8   360   175  3.15 3.440 17.02     0     0     3     2     2
## 6:  18.1     6   225   105  2.76 3.460 20.22     1     0     3     1     6
# You can drop variables by setting them to NULL
mtcars %>%
    let(cyl = NULL) %>%
    head()
##      mpg  disp    hp  drat    wt  qsec    vs    am  gear  carb
##    <num> <num> <num> <num> <num> <num> <num> <num> <num> <num>
## 1:  21.0   160   110  3.90 2.620 16.46     0     1     4     4
## 2:  21.0   160   110  3.90 2.875 17.02     0     1     4     4
## 3:  22.8   108    93  3.85 2.320 18.61     1     1     4     1
## 4:  21.4   258   110  3.08 3.215 19.44     1     0     3     1
## 5:  18.7   360   175  3.15 3.440 17.02     0     0     3     2
## 6:  18.1   225   105  2.76 3.460 20.22     1     0     3     1
# keeps all existing variables
mtcars %>%
    let(displ_l = disp / 61.0237) %>%
    head()
##      mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb  displ_l
##    <num> <num> <num> <num> <num> <num> <num> <num> <num> <num> <num>    <num>
## 1:  21.0     6   160   110  3.90 2.620 16.46     0     1     4     4 2.621932
## 2:  21.0     6   160   110  3.90 2.875 17.02     0     1     4     4 2.621932
## 3:  22.8     4   108    93  3.85 2.320 18.61     1     1     4     1 1.769804
## 4:  21.4     6   258   110  3.08 3.215 19.44     1     0     3     1 4.227866
## 5:  18.7     8   360   175  3.15 3.440 17.02     0     0     3     2 5.899347
## 6:  18.1     6   225   105  2.76 3.460 20.22     1     0     3     1 3.687092
# keeps only the variables you create
mtcars %>%
    take(displ_l = disp / 61.0237) %>% 
    head()
##     displ_l
##       <num>
## 1: 2.621932
## 2: 2.621932
## 3: 1.769804
## 4: 4.227866
## 5: 5.899347
## 6: 3.687092
# can refer to both contextual variables and variable names:
var = 100
mtcars %>%
    let(cyl = cyl * var) %>%
    head()
##      mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb
##    <num> <num> <num> <num> <num> <num> <num> <num> <num> <num> <num>
## 1:  21.0   600   160   110  3.90 2.620 16.46     0     1     4     4
## 2:  21.0   600   160   110  3.90 2.875 17.02     0     1     4     4
## 3:  22.8   400   108    93  3.85 2.320 18.61     1     1     4     1
## 4:  21.4   600   258   110  3.08 3.215 19.44     1     0     3     1
## 5:  18.7   800   360   175  3.15 3.440 17.02     0     0     3     2
## 6:  18.1   600   225   105  2.76 3.460 20.22     1     0     3     1
# select rows
mtcars %>%
    rows(am==0) %>% 
    head()
##      mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb
##    <num> <num> <num> <num> <num> <num> <num> <num> <num> <num> <num>
## 1:  21.4     6 258.0   110  3.08 3.215 19.44     1     0     3     1
## 2:  18.7     8 360.0   175  3.15 3.440 17.02     0     0     3     2
## 3:  18.1     6 225.0   105  2.76 3.460 20.22     1     0     3     1
## 4:  14.3     8 360.0   245  3.21 3.570 15.84     0     0     3     4
## 5:  24.4     4 146.7    62  3.69 3.190 20.00     1     0     4     2
## 6:  22.8     4 140.8    95  3.92 3.150 22.90     1     0     4     2
# select rows with compound condition
mtcars %>%
    rows(am==0 & mpg>mean(mpg))
##      mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb
##    <num> <num> <num> <num> <num> <num> <num> <num> <num> <num> <num>
## 1:  21.4     6 258.0   110  3.08 3.215 19.44     1     0     3     1
## 2:  24.4     4 146.7    62  3.69 3.190 20.00     1     0     4     2
## 3:  22.8     4 140.8    95  3.92 3.150 22.90     1     0     4     2
## 4:  21.5     4 120.1    97  3.70 2.465 20.01     1     0     3     1
# select columns
mtcars %>% 
    columns(vs:carb, cyl)
##                     vs am gear carb cyl
## Mazda RX4            0  1    4    4   6
## Mazda RX4 Wag        0  1    4    4   6
## Datsun 710           1  1    4    1   4
## Hornet 4 Drive       1  0    3    1   6
## Hornet Sportabout    0  0    3    2   8
## Valiant              1  0    3    1   6
## Duster 360           0  0    3    4   8
## Merc 240D            1  0    4    2   4
## Merc 230             1  0    4    2   4
## Merc 280             1  0    4    4   6
## Merc 280C            1  0    4    4   6
## Merc 450SE           0  0    3    3   8
## Merc 450SL           0  0    3    3   8
## Merc 450SLC          0  0    3    3   8
## Cadillac Fleetwood   0  0    3    4   8
## Lincoln Continental  0  0    3    4   8
## Chrysler Imperial    0  0    3    4   8
## Fiat 128             1  1    4    1   4
## Honda Civic          1  1    4    2   4
## Toyota Corolla       1  1    4    1   4
## Toyota Corona        1  0    3    1   4
## Dodge Challenger     0  0    3    2   8
## AMC Javelin          0  0    3    2   8
## Camaro Z28           0  0    3    4   8
## Pontiac Firebird     0  0    3    2   8
## Fiat X1-9            1  1    4    1   4
## Porsche 914-2        0  1    5    2   4
## Lotus Europa         1  1    5    2   4
## Ford Pantera L       0  1    5    4   8
## Ferrari Dino         0  1    5    6   6
## Maserati Bora        0  1    5    8   8
## Volvo 142E           1  1    4    2   4
mtcars %>% 
    columns(-am, -cyl)    
##                      mpg  disp  hp drat    wt  qsec vs gear carb
## Mazda RX4           21.0 160.0 110 3.90 2.620 16.46  0    4    4
## Mazda RX4 Wag       21.0 160.0 110 3.90 2.875 17.02  0    4    4
## Datsun 710          22.8 108.0  93 3.85 2.320 18.61  1    4    1
## Hornet 4 Drive      21.4 258.0 110 3.08 3.215 19.44  1    3    1
## Hornet Sportabout   18.7 360.0 175 3.15 3.440 17.02  0    3    2
## Valiant             18.1 225.0 105 2.76 3.460 20.22  1    3    1
## Duster 360          14.3 360.0 245 3.21 3.570 15.84  0    3    4
## Merc 240D           24.4 146.7  62 3.69 3.190 20.00  1    4    2
## Merc 230            22.8 140.8  95 3.92 3.150 22.90  1    4    2
## Merc 280            19.2 167.6 123 3.92 3.440 18.30  1    4    4
## Merc 280C           17.8 167.6 123 3.92 3.440 18.90  1    4    4
## Merc 450SE          16.4 275.8 180 3.07 4.070 17.40  0    3    3
## Merc 450SL          17.3 275.8 180 3.07 3.730 17.60  0    3    3
## Merc 450SLC         15.2 275.8 180 3.07 3.780 18.00  0    3    3
## Cadillac Fleetwood  10.4 472.0 205 2.93 5.250 17.98  0    3    4
## Lincoln Continental 10.4 460.0 215 3.00 5.424 17.82  0    3    4
## Chrysler Imperial   14.7 440.0 230 3.23 5.345 17.42  0    3    4
## Fiat 128            32.4  78.7  66 4.08 2.200 19.47  1    4    1
## Honda Civic         30.4  75.7  52 4.93 1.615 18.52  1    4    2
## Toyota Corolla      33.9  71.1  65 4.22 1.835 19.90  1    4    1
## Toyota Corona       21.5 120.1  97 3.70 2.465 20.01  1    3    1
## Dodge Challenger    15.5 318.0 150 2.76 3.520 16.87  0    3    2
## AMC Javelin         15.2 304.0 150 3.15 3.435 17.30  0    3    2
## Camaro Z28          13.3 350.0 245 3.73 3.840 15.41  0    3    4
## Pontiac Firebird    19.2 400.0 175 3.08 3.845 17.05  0    3    2
## Fiat X1-9           27.3  79.0  66 4.08 1.935 18.90  1    4    1
## Porsche 914-2       26.0 120.3  91 4.43 2.140 16.70  0    5    2
## Lotus Europa        30.4  95.1 113 3.77 1.513 16.90  1    5    2
## Ford Pantera L      15.8 351.0 264 4.22 3.170 14.50  0    5    4
## Ferrari Dino        19.7 145.0 175 3.62 2.770 15.50  0    5    6
## Maserati Bora       15.0 301.0 335 3.54 3.570 14.60  0    5    8
## Volvo 142E          21.4 121.0 109 4.11 2.780 18.60  1    4    2
# regular expression pattern
columns(iris, "^Petal") %>% head() # variables which start from 'Petal'
##   Petal.Length Petal.Width
## 1          1.4         0.2
## 2          1.4         0.2
## 3          1.3         0.2
## 4          1.5         0.2
## 5          1.4         0.2
## 6          1.7         0.4
columns(iris, "Width$") %>% head() # variables which end with 'Width'
##   Sepal.Width Petal.Width
## 1         3.5         0.2
## 2         3.0         0.2
## 3         3.2         0.2
## 4         3.1         0.2
## 5         3.6         0.2
## 6         3.9         0.4
# move Species variable to the front
# pattern "^." matches all variables
columns(iris, Species, "^.") %>% head()
##   Species Sepal.Length Sepal.Width Petal.Length Petal.Width
## 1  setosa          5.1         3.5          1.4         0.2
## 2  setosa          4.9         3.0          1.4         0.2
## 3  setosa          4.7         3.2          1.3         0.2
## 4  setosa          4.6         3.1          1.5         0.2
## 5  setosa          5.0         3.6          1.4         0.2
## 6  setosa          5.4         3.9          1.7         0.4
# pattern "^.*al" means "contains 'al'"
columns(iris, "^.*al") %>% head()
##   Sepal.Length Sepal.Width Petal.Length Petal.Width
## 1          5.1         3.5          1.4         0.2
## 2          4.9         3.0          1.4         0.2
## 3          4.7         3.2          1.3         0.2
## 4          4.6         3.1          1.5         0.2
## 5          5.0         3.6          1.4         0.2
## 6          5.4         3.9          1.7         0.4
# numeric indexing - all variables except Species
columns(iris, 1:4) %>% head()
##   Sepal.Length Sepal.Width Petal.Length Petal.Width
## 1          5.1         3.5          1.4         0.2
## 2          4.9         3.0          1.4         0.2
## 3          4.7         3.2          1.3         0.2
## 4          4.6         3.1          1.5         0.2
## 5          5.0         3.6          1.4         0.2
## 6          5.4         3.9          1.7         0.4
# A 'take' with summary functions applied without 'by' argument returns an aggregated data
mtcars %>%
    take(mean = mean(disp), n = .N)
##        mean     n
##       <num> <int>
## 1: 230.7219    32
# Usually, you'll want to group first
mtcars %>%
    take(mean = mean(disp), n = .N, by = am)
##       am     mean     n
##    <num>    <num> <int>
## 1:     1 143.5308    13
## 2:     0 290.3789    19
# grouping by multiple variables
mtcars %>%
    take(mean = mean(disp), n = .N, by = list(am, vs))
##       am    vs     mean     n
##    <num> <num>    <num> <int>
## 1:     1     0 206.2167     6
## 2:     1     1  89.8000     7
## 3:     0     1 175.1143     7
## 4:     0     0 357.6167    12
# You can group by expressions:
mtcars %>%
    take_all(
        mean,
        by = list(vsam = vs + am)
    )
##     vsam      mpg      cyl     disp        hp     drat       wt     qsec
##    <num>    <num>    <num>    <num>     <num>    <num>    <num>    <num>
## 1:     1 20.28462 5.692308 189.4692 138.46154 3.738462 3.038846 18.04231
## 2:     2 28.37143 4.000000  89.8000  80.57143 4.148571 2.028286 18.70000
## 3:     0 15.05000 8.000000 357.6167 194.16667 3.120833 4.104083 17.14250
##        gear     carb
##       <num>    <num>
## 1: 4.076923 3.307692
## 2: 4.142857 1.428571
## 3: 3.000000 3.083333
# modify all non-grouping variables in-place
mtcars %>%
    let_all((.x - mean(.x))/sd(.x), by = am) %>%
    head()
##           mpg        cyl       disp         hp       drat         wt       qsec
##         <num>      <num>      <num>      <num>      <num>      <num>      <num>
## 1: -0.5501185  0.5945745  0.1888587 -0.2004008 -0.4120299  0.3387459 -0.5021316
## 2: -0.5501185  0.5945745  0.1888587 -0.2004008 -0.4120299  0.7520483 -0.1896942
## 3: -0.2582189 -0.6936702 -0.4074443 -0.4026317 -0.5493732 -0.1474922  0.6974050
## 4:  1.1091990 -0.6133196 -0.2938955 -0.9323843 -0.5259081 -0.7124963  0.7176592
## 5:  0.4049674  0.6814663  0.6319326  0.2733692 -0.3474750 -0.4230701 -0.6641654
## 6:  0.2484716 -0.6133196 -0.5934281 -1.0251346 -1.3416023 -0.3973433  1.1630407
##            vs    am       gear       carb
##         <num> <num>      <num>      <num>
## 1: -1.0377490     1 -0.7595545  0.4944600
## 2: -1.0377490     1 -0.7595545  0.4944600
## 3:  0.8894992     1 -0.7595545 -0.8829642
## 4:  1.2743862     0 -0.5026247 -1.5141438
## 5: -0.7433919     0 -0.5026247 -0.6423641
## 6:  1.2743862     0 -0.5026247 -1.5141438
# modify all non-grouping variables to new variables
mtcars %>%
    let_all(scaled = (.x - mean(.x))/sd(.x), by = am) %>%
    head()
##      mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb mpg_scaled
##    <num> <num> <num> <num> <num> <num> <num> <num> <num> <num> <num>      <num>
## 1:  21.0     6   160   110  3.90 2.620 16.46     0     1     4     4 -0.5501185
## 2:  21.0     6   160   110  3.90 2.875 17.02     0     1     4     4 -0.5501185
## 3:  22.8     4   108    93  3.85 2.320 18.61     1     1     4     1 -0.2582189
## 4:  21.4     6   258   110  3.08 3.215 19.44     1     0     3     1  1.1091990
## 5:  18.7     8   360   175  3.15 3.440 17.02     0     0     3     2  0.4049674
## 6:  18.1     6   225   105  2.76 3.460 20.22     1     0     3     1  0.2484716
##    cyl_scaled disp_scaled  hp_scaled drat_scaled  wt_scaled qsec_scaled
##         <num>       <num>      <num>       <num>      <num>       <num>
## 1:  0.5945745   0.1888587 -0.2004008  -0.4120299  0.3387459  -0.5021316
## 2:  0.5945745   0.1888587 -0.2004008  -0.4120299  0.7520483  -0.1896942
## 3: -0.6936702  -0.4074443 -0.4026317  -0.5493732 -0.1474922   0.6974050
## 4: -0.6133196  -0.2938955 -0.9323843  -0.5259081 -0.7124963   0.7176592
## 5:  0.6814663   0.6319326  0.2733692  -0.3474750 -0.4230701  -0.6641654
## 6: -0.6133196  -0.5934281 -1.0251346  -1.3416023 -0.3973433   1.1630407
##     vs_scaled gear_scaled carb_scaled
##         <num>       <num>       <num>
## 1: -1.0377490  -0.7595545   0.4944600
## 2: -1.0377490  -0.7595545   0.4944600
## 3:  0.8894992  -0.7595545  -0.8829642
## 4:  1.2743862  -0.5026247  -1.5141438
## 5: -0.7433919  -0.5026247  -0.6423641
## 6:  1.2743862  -0.5026247  -1.5141438
# conditionally modify all variables
iris %>%
    let_all(mean = if(is.numeric(.x)) mean(.x)) %>%
    head()
##    Sepal.Length Sepal.Width Petal.Length Petal.Width Species Sepal.Length_mean
##           <num>       <num>        <num>       <num>  <fctr>             <num>
## 1:          5.1         3.5          1.4         0.2  setosa          5.843333
## 2:          4.9         3.0          1.4         0.2  setosa          5.843333
## 3:          4.7         3.2          1.3         0.2  setosa          5.843333
## 4:          4.6         3.1          1.5         0.2  setosa          5.843333
## 5:          5.0         3.6          1.4         0.2  setosa          5.843333
## 6:          5.4         3.9          1.7         0.4  setosa          5.843333
##    Sepal.Width_mean Petal.Length_mean Petal.Width_mean
##               <num>             <num>            <num>
## 1:         3.057333             3.758         1.199333
## 2:         3.057333             3.758         1.199333
## 3:         3.057333             3.758         1.199333
## 4:         3.057333             3.758         1.199333
## 5:         3.057333             3.758         1.199333
## 6:         3.057333             3.758         1.199333
# modify all variables conditionally on name
iris %>%
    let_all(
        mean = if(startsWith(.name, "Sepal")) mean(.x),
        median = if(startsWith(.name, "Petal")) median(.x),
        by = Species
    ) %>%
    head()
##    Sepal.Length Sepal.Width Petal.Length Petal.Width Species Sepal.Length_mean
##           <num>       <num>        <num>       <num>  <fctr>             <num>
## 1:          5.1         3.5          1.4         0.2  setosa             5.006
## 2:          4.9         3.0          1.4         0.2  setosa             5.006
## 3:          4.7         3.2          1.3         0.2  setosa             5.006
## 4:          4.6         3.1          1.5         0.2  setosa             5.006
## 5:          5.0         3.6          1.4         0.2  setosa             5.006
## 6:          5.4         3.9          1.7         0.4  setosa             5.006
##    Sepal.Width_mean Petal.Length_median Petal.Width_median
##               <num>               <num>              <num>
## 1:            3.428                 1.5                0.2
## 2:            3.428                 1.5                0.2
## 3:            3.428                 1.5                0.2
## 4:            3.428                 1.5                0.2
## 5:            3.428                 1.5                0.2
## 6:            3.428                 1.5                0.2
# aggregation with 'take_all'
mtcars %>%
    take_all(mean = mean(.x), sd = sd(.x), n = .N, by = am)
##       am mpg_mean cyl_mean disp_mean  hp_mean drat_mean  wt_mean qsec_mean
##    <num>    <num>    <num>     <num>    <num>     <num>    <num>     <num>
## 1:     1 24.39231 5.076923  143.5308 126.8462  4.050000 2.411000  17.36000
## 2:     0 17.14737 6.947368  290.3789 160.2632  3.286316 3.768895  18.18316
##      vs_mean gear_mean carb_mean   mpg_sd   cyl_sd   disp_sd    hp_sd   drat_sd
##        <num>     <num>     <num>    <num>    <num>     <num>    <num>     <num>
## 1: 0.5384615  4.384615  2.923077 6.166504 1.552500  87.20399 84.06232 0.3640513
## 2: 0.3684211  3.210526  2.736842 3.833966 1.544657 110.17165 53.90820 0.3923039
##        wt_sd  qsec_sd     vs_sd   gear_sd  carb_sd mpg_n cyl_n disp_n  hp_n
##        <num>    <num>     <num>     <num>    <num> <int> <int>  <int> <int>
## 1: 0.6169816 1.792359 0.5188745 0.5063697 2.177978    13    13     13    13
## 2: 0.7774001 1.751308 0.4955946 0.4188539 1.147079    19    19     19    19
##    drat_n  wt_n qsec_n  vs_n gear_n carb_n
##     <int> <int>  <int> <int>  <int>  <int>
## 1:     13    13     13    13     13     13
## 2:     19    19     19    19     19     19
# conditionally aggregate all variables
iris %>%
    take_all(mean = if(is.numeric(.x)) mean(.x))
##    Sepal.Length_mean Sepal.Width_mean Petal.Length_mean Petal.Width_mean
##                <num>            <num>             <num>            <num>
## 1:          5.843333         3.057333             3.758         1.199333
# aggregate all variables conditionally on name
iris %>%
    take_all(
        mean = if(startsWith(.name, "Sepal")) mean(.x),
        median = if(startsWith(.name, "Petal")) median(.x),
        by = Species
    )
##       Species Sepal.Length_mean Sepal.Width_mean Petal.Length_median
##        <fctr>             <num>            <num>               <num>
## 1:     setosa             5.006            3.428                1.50
## 2: versicolor             5.936            2.770                4.35
## 3:  virginica             6.588            2.974                5.55
##    Petal.Width_median
##                 <num>
## 1:                0.2
## 2:                1.3
## 3:                2.0
# parametric evaluation:
var = quote(mean(cyl))
mtcars %>% 
    let(mean_cyl = eval(var)) %>% 
    head()
##      mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb mean_cyl
##    <num> <num> <num> <num> <num> <num> <num> <num> <num> <num> <num>    <num>
## 1:  21.0     6   160   110  3.90 2.620 16.46     0     1     4     4   6.1875
## 2:  21.0     6   160   110  3.90 2.875 17.02     0     1     4     4   6.1875
## 3:  22.8     4   108    93  3.85 2.320 18.61     1     1     4     1   6.1875
## 4:  21.4     6   258   110  3.08 3.215 19.44     1     0     3     1   6.1875
## 5:  18.7     8   360   175  3.15 3.440 17.02     0     0     3     2   6.1875
## 6:  18.1     6   225   105  2.76 3.460 20.22     1     0     3     1   6.1875
take(mtcars, eval(var))
##    eval(var)
##        <num>
## 1:    6.1875
# all together
new_var = "mean_cyl"
mtcars %>% 
    let((new_var) := eval(var)) %>% 
    head()
##      mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb mean_cyl
##    <num> <num> <num> <num> <num> <num> <num> <num> <num> <num> <num>    <num>
## 1:  21.0     6   160   110  3.90 2.620 16.46     0     1     4     4   6.1875
## 2:  21.0     6   160   110  3.90 2.875 17.02     0     1     4     4   6.1875
## 3:  22.8     4   108    93  3.85 2.320 18.61     1     1     4     1   6.1875
## 4:  21.4     6   258   110  3.08 3.215 19.44     1     0     3     1   6.1875
## 5:  18.7     8   360   175  3.15 3.440 17.02     0     0     3     2   6.1875
## 6:  18.1     6   225   105  2.76 3.460 20.22     1     0     3     1   6.1875
take(mtcars, (new_var) := eval(var))
##    mean_cyl
##       <num>
## 1:   6.1875

Variable selection in the expressions

You can use ‘columns’ inside expression in the ‘take’/‘let’. ‘columns’ will be replaced with data.table with selected columns. In ‘let’ in the expressions with ‘:=’, ‘cols’ or ‘%to%’ can be placed in the left part of the expression. It is usefull for multiple assignment. There are four ways of column selection:

  1. Simply by column names
  2. By variable ranges, e. g. vs:carb. Alternatively, you can use ‘%to%’ instead of colon: ‘vs %to% carb’.
  3. With regular expressions. Characters which start with ‘^’ or end with $ considered as Perl-style regular expression patterns. For example, ‘^Petal’ returns all variables started with ‘Petal’. ‘Width$’ returns all variables which end with ‘Width’. Pattern ‘^.’ matches all variables and pattern ’^.*my_str’ is equivalent to contains “my_str”’.
  4. By character variables with interpolated parts. Expression in the curly brackets inside characters will be evaluated in the parent frame with ‘text_expand’ function. For example, a{1:3} will be transformed to the names ‘a1’, ‘a2’, ‘a3’. ‘cols’ is just a shortcut for ‘columns’.
# range selection
iris %>% 
    let(
        avg = rowMeans(Sepal.Length %to% Petal.Width)
    ) %>% 
    head()
##    Sepal.Length Sepal.Width Petal.Length Petal.Width Species   avg
##           <num>       <num>        <num>       <num>  <fctr> <num>
## 1:          5.1         3.5          1.4         0.2  setosa 2.550
## 2:          4.9         3.0          1.4         0.2  setosa 2.375
## 3:          4.7         3.2          1.3         0.2  setosa 2.350
## 4:          4.6         3.1          1.5         0.2  setosa 2.350
## 5:          5.0         3.6          1.4         0.2  setosa 2.550
## 6:          5.4         3.9          1.7         0.4  setosa 2.850
# multiassignment
iris %>% 
    let(
        # starts with Sepal or Petal
        multipled1 %to% multipled4 := cols("^(Sepal|Petal)")*2
    ) %>% 
    head()
##    Sepal.Length Sepal.Width Petal.Length Petal.Width Species multipled1
##           <num>       <num>        <num>       <num>  <fctr>      <num>
## 1:          5.1         3.5          1.4         0.2  setosa       10.2
## 2:          4.9         3.0          1.4         0.2  setosa        9.8
## 3:          4.7         3.2          1.3         0.2  setosa        9.4
## 4:          4.6         3.1          1.5         0.2  setosa        9.2
## 5:          5.0         3.6          1.4         0.2  setosa       10.0
## 6:          5.4         3.9          1.7         0.4  setosa       10.8
##    multipled2 multipled3 multipled4
##         <num>      <num>      <num>
## 1:        7.0        2.8        0.4
## 2:        6.0        2.8        0.4
## 3:        6.4        2.6        0.4
## 4:        6.2        3.0        0.4
## 5:        7.2        2.8        0.4
## 6:        7.8        3.4        0.8
mtcars %>% 
    let(
        # text expansion
        cols("scaled_{names(mtcars)}") := lapply(cols("{names(mtcars)}"), scale)
    ) %>% 
    head()
##      mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb scaled_mpg
##    <num> <num> <num> <num> <num> <num> <num> <num> <num> <num> <num>      <num>
## 1:  21.0     6   160   110  3.90 2.620 16.46     0     1     4     4  0.1508848
## 2:  21.0     6   160   110  3.90 2.875 17.02     0     1     4     4  0.1508848
## 3:  22.8     4   108    93  3.85 2.320 18.61     1     1     4     1  0.4495434
## 4:  21.4     6   258   110  3.08 3.215 19.44     1     0     3     1  0.2172534
## 5:  18.7     8   360   175  3.15 3.440 17.02     0     0     3     2 -0.2307345
## 6:  18.1     6   225   105  2.76 3.460 20.22     1     0     3     1 -0.3302874
##    scaled_cyl scaled_disp  scaled_hp scaled_drat    scaled_wt scaled_qsec
##         <num>       <num>      <num>       <num>        <num>       <num>
## 1: -0.1049878 -0.57061982 -0.5350928   0.5675137 -0.610399567  -0.7771651
## 2: -0.1049878 -0.57061982 -0.5350928   0.5675137 -0.349785269  -0.4637808
## 3: -1.2248578 -0.99018209 -0.7830405   0.4739996 -0.917004624   0.4260068
## 4: -0.1049878  0.22009369 -0.5350928  -0.9661175 -0.002299538   0.8904872
## 5:  1.0148821  1.04308123  0.4129422  -0.8351978  0.227654255  -0.4637808
## 6: -0.1049878 -0.04616698 -0.6080186  -1.5646078  0.248094592   1.3269868
##     scaled_vs  scaled_am scaled_gear scaled_carb
##         <num>      <num>       <num>       <num>
## 1: -0.8680278  1.1899014   0.4235542   0.7352031
## 2: -0.8680278  1.1899014   0.4235542   0.7352031
## 3:  1.1160357  1.1899014   0.4235542  -1.1221521
## 4:  1.1160357 -0.8141431  -0.9318192  -1.1221521
## 5: -0.8680278 -0.8141431  -0.9318192  -0.5030337
## 6:  1.1160357 -0.8141431  -0.9318192  -1.1221521
# range selection in 'by'
# selection of range + additional column
mtcars %>% 
    take(
        res = sum(cols(mpg, disp %to% drat)),
        by = vs %to% gear
    )
##       vs    am  gear     res
##    <num> <num> <num>   <num>
## 1:     0     1     4  589.80
## 2:     1     1     4 1177.97
## 3:     1     0     3  985.64
## 4:     0     0     3 6839.45
## 5:     1     0     4 1125.35
## 6:     0     1     5 1874.61
## 7:     1     1     5  242.27

Joins

Here we use the same datasets as with lookups:

workers = fread("
    name company
    Nick Acme
    John Ajax
    Daniela Ajax
")

positions = fread("
    name position
    John designer
    Daniela engineer
    Cathie manager
")

workers
##       name company
##     <char>  <char>
## 1:    Nick    Acme
## 2:    John    Ajax
## 3: Daniela    Ajax
positions
##       name position
##     <char>   <char>
## 1:    John designer
## 2: Daniela engineer
## 3:  Cathie  manager

Different kinds of joins:

workers %>% dt_inner_join(positions)
## dt_inner_join: joining, by = "name"
##       name company position
##     <char>  <char>   <char>
## 1:    John    Ajax designer
## 2: Daniela    Ajax engineer
workers %>% dt_left_join(positions)
## dt_left_join: joining, by = "name"
##       name company position
##     <char>  <char>   <char>
## 1:    Nick    Acme     <NA>
## 2:    John    Ajax designer
## 3: Daniela    Ajax engineer
workers %>% dt_right_join(positions)
## dt_right_join: joining, by = "name"
##       name company position
##     <char>  <char>   <char>
## 1:    John    Ajax designer
## 2: Daniela    Ajax engineer
## 3:  Cathie    <NA>  manager
workers %>% dt_full_join(positions)
## dt_full_join: joining, by = "name"
##       name company position
##     <char>  <char>   <char>
## 1:    Nick    Acme     <NA>
## 2:    John    Ajax designer
## 3: Daniela    Ajax engineer
## 4:  Cathie    <NA>  manager
# filtering joins
workers %>% dt_anti_join(positions)
## dt_anti_join: joining, by = "name"
##      name company
##    <char>  <char>
## 1:   Nick    Acme
workers %>% dt_semi_join(positions)
## dt_semi_join: joining, by = "name"
##       name company
##     <char>  <char>
## 1:    John    Ajax
## 2: Daniela    Ajax

To suppress the message, supply by argument:

workers %>% dt_left_join(positions, by = "name")

Use a named by if the join variables have different names:

positions2 = setNames(positions, c("worker", "position")) # rename first column in 'positions'
workers %>% dt_inner_join(positions2, by = c("name" = "worker"))

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.