``

library(tidyverse)
-- Attaching packages --------------------------------------- tidyverse 1.2.1 --
v ggplot2 2.2.1     v purrr   0.2.4
v tibble  1.4.2     v dplyr   0.7.4
v tidyr   0.8.0     v stringr 1.3.0
v readr   1.1.1     v forcats 0.3.0
-- Conflicts ------------------------------------------ tidyverse_conflicts() --
x dplyr::filter() masks stats::filter()
x dplyr::lag()    masks stats::lag()

Add or modify a variable

new_df <- function() {
  tribble(
      ~ name, ~ age,
      "Reed",   14L,
    "Wesley",   12L,
       "Eli",   12L,
      "Toby",    1L
  )
}
df <- new_df()
new_df() %>%
  mutate(
    eyes = 2L,
    snack = c("chips", "cheese"),
    uname = toupper(name)
  )
Error in mutate_impl(.data, dots) : 
  Column `snack` must be length 4 (the number of rows) or one, not 2
new_df() %>%
  mutate(
    eyes = 2L,
    snack = c("chips", "cheese", "mixed nuts", "nerf bullets"),
    uname = toupper(name)
  )
# A tibble: 4 x 5
  name     age  eyes snack        uname 
  <chr>  <int> <int> <chr>        <chr> 
1 Reed      14     2 chips        REED  
2 Wesley    12     2 cheese       WESLEY
3 Eli       12     2 mixed nuts   ELI   
4 Toby       1     2 nerf bullets TOBY  

Are you absolutely sure that you, personally, need to iterate over rows?

paste(df$name[1], "is", df$age[1], "years old")
[1] "Reed is 14 years old"
n <- nrow(df)
s <- vector(mode = "character", length = n)
for (i in seq_len(n)) {
  s[i] <- paste(df$name[i], "is", df$age[i], "years old")
}
s
[1] "Reed is 14 years old"   "Wesley is 12 years old"
[3] "Eli is 12 years old"    "Toby is 1 years old"   
paste(df$name, "is", df$age, "years old")
[1] "Reed is 14 years old"   "Wesley is 12 years old"
[3] "Eli is 12 years old"    "Toby is 1 years old"   
str_glue_data(df, "{name} is {age} years old")
Reed is 14 years old
Wesley is 12 years old
Eli is 12 years old
Toby is 1 years old
df %>%
  mutate(sentence = str_glue("{name} is {age} years old"))
# A tibble: 4 x 3
  name     age sentence              
  <chr>  <int> <chr>                 
1 Reed      14 Reed is 14 years old  
2 Wesley    12 Wesley is 12 years old
3 Eli       12 Eli is 12 years old   
4 Toby       1 Toby is 1 years old   

Working with non-vectorized functions

df_list <- list(
  iris = head(iris, 2),
  mtcars = head(mtcars, 3)
)
df_list
$`iris`
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa

$mtcars
               mpg cyl disp  hp drat    wt  qsec vs am gear carb
Mazda RX4     21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
Mazda RX4 Wag 21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
Datsun 710    22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
nrow(df_list)
NULL
library(purrr)
map(df_list, nrow)
$`iris`
[1] 2

$mtcars
[1] 3
map(df_list, ~ nrow(.x))
$`iris`
[1] 2

$mtcars
[1] 3

Row-wise thinking vs. column-wise thinking

x <- list(
  list(name = "sue", number = 1, veg = c("onion", "carrot")),
  list(name = "doug", number = 2, veg = c("potato", "beet"))
)
x
[[1]]
[[1]]$`name`
[1] "sue"

[[1]]$number
[1] 1

[[1]]$veg
[1] "onion"  "carrot"


[[2]]
[[2]]$`name`
[1] "doug"

[[2]]$number
[1] 2

[[2]]$veg
[1] "potato" "beet"  
tibble(
  name = map_chr(x, "name"),
  number = map_dbl(x, "number"),
  veg = map(x, "veg")
)
# A tibble: 2 x 3
  name  number veg      
  <chr>  <dbl> <list>   
1 sue        1 <chr [2]>
2 doug       2 <chr [2]>

Work on groups of rows via dplyr::group_by() + summarise()

as.tibble(iris)
# A tibble: 150 x 5
   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
          <dbl>       <dbl>        <dbl>       <dbl> <fct>  
 1          5.1         3.5          1.4         0.2 setosa 
 2          4.9         3            1.4         0.2 setosa 
 3          4.7         3.2          1.3         0.2 setosa 
 4          4.6         3.1          1.5         0.2 setosa 
 5          5           3.6          1.4         0.2 setosa 
 6          5.4         3.9          1.7         0.4 setosa 
 7          4.6         3.4          1.4         0.3 setosa 
 8          5           3.4          1.5         0.2 setosa 
 9          4.4         2.9          1.4         0.2 setosa 
10          4.9         3.1          1.5         0.1 setosa 
# ... with 140 more rows
iris %>%
  group_by(Species) %>%
  summarise(pl_avg = mean(Petal.Length), pw_avg = mean(Petal.Width))
# A tibble: 3 x 3
  Species    pl_avg pw_avg
  <fct>       <dbl>  <dbl>
1 setosa       1.46  0.246
2 versicolor   4.26  1.33 
3 virginica    5.55  2.03 

What if you want to return summaries that are not just a single number?

iris %>%
  group_by(Species) %>%
  summarise(pl_qtile = quantile(Petal.Length, c(0.25, 0.5, 0.75)))
Error in summarise_impl(.data, dots) : 
  Column `pl_qtile` must be length 1 (a summary value), not 3
iris %>%
  group_by(Species) %>%
  summarise(pl_qtile = list(quantile(Petal.Length, c(0.25, 0.5, 0.75))))
# A tibble: 3 x 2
  Species    pl_qtile 
  <fct>      <list>   
1 setosa     <dbl [3]>
2 versicolor <dbl [3]>
3 virginica  <dbl [3]>
iris %>%
  group_by(Species) %>%
  summarise(pl_qtile = list(quantile(Petal.Length, c(0.25, 0.5, 0.75)))) %>%
  mutate(pl_qtile = map(pl_qtile, enframe, name = "quantile")) %>%
  unnest() %>%
  mutate(quantile = factor(quantile)) %>% 
  spread(quantile, value)
# A tibble: 3 x 4
  Species    `25%` `50%` `75%`
  <fct>      <dbl> <dbl> <dbl>
1 setosa       1.4  1.5   1.58
2 versicolor   4    4.35  4.6 
3 virginica    5.1  5.55  5.88

Row-wise Summaries

df <- tribble(
  ~ name, ~ t1, ~t2, ~t3,
  "Abby",    1,   2,   3,
  "Bess",    4,   5,   6,
  "Carl",    7,   8,   9
)
df
# A tibble: 3 x 4
  name     t1    t2    t3
  <chr> <dbl> <dbl> <dbl>
1 Abby      1     2     3
2 Bess      4     5     6
3 Carl      7     8     9
df %>%
  mutate(t_sum = rowSums(select_if(., is.numeric)))
# A tibble: 3 x 5
  name     t1    t2    t3 t_sum
  <chr> <dbl> <dbl> <dbl> <dbl>
1 Abby      1     2     3     6
2 Bess      4     5     6    15
3 Carl      7     8     9    24
df %>%
  mutate(t_avg = rowMeans(select(., -name)))
# A tibble: 3 x 5
  name     t1    t2    t3 t_avg
  <chr> <dbl> <dbl> <dbl> <dbl>
1 Abby      1     2     3     2
2 Bess      4     5     6     5
3 Carl      7     8     9     8

THIS!

df %>%
  mutate(t_avg = rowSums(select(., c(t1, t3))))
# A tibble: 3 x 5
  name     t1    t2    t3 t_avg
  <chr> <dbl> <dbl> <dbl> <dbl>
1 Abby      1     2     3     4
2 Bess      4     5     6    10
3 Carl      7     8     9    16
LS0tDQp0aXRsZTogIlJvdyBvcmllbnRlZCB3b3JrZmxvdyINCm91dHB1dDogDQogIGh0bWxfbm90ZWJvb2s6IA0KICAgIHRvYzogeWVzDQogICAgdG9jX2Zsb2F0OiB0cnVlDQogICAgZmlnX2NhcHRpb246IHRydWUNCi0tLQ0KYGANCmBgYHtyfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpgYGANCg0KIyBBZGQgb3IgbW9kaWZ5IGEgdmFyaWFibGUNCmBgYHtyfQ0KbmV3X2RmIDwtIGZ1bmN0aW9uKCkgew0KICB0cmliYmxlKA0KICAgICAgfiBuYW1lLCB+IGFnZSwNCiAgICAgICJSZWVkIiwgICAxNEwsDQogICAgIldlc2xleSIsICAgMTJMLA0KICAgICAgICJFbGkiLCAgIDEyTCwNCiAgICAgICJUb2J5IiwgICAgMUwNCiAgKQ0KfQ0KYGBgDQoNCmBgYHtyfQ0KZGYgPC0gbmV3X2RmKCkNCmBgYA0KDQpgYGB7cn0NCm5ld19kZigpICU+JQ0KICBtdXRhdGUoDQogICAgZXllcyA9IDJMLA0KICAgIHNuYWNrID0gYygiY2hpcHMiLCAiY2hlZXNlIiksDQogICAgdW5hbWUgPSB0b3VwcGVyKG5hbWUpDQogICkNCmBgYA0KYGBge3J9DQpuZXdfZGYoKSAlPiUNCiAgbXV0YXRlKA0KICAgIGV5ZXMgPSAyTCwNCiAgICBzbmFjayA9IGMoImNoaXBzIiwgImNoZWVzZSIsICJtaXhlZCBudXRzIiwgIm5lcmYgYnVsbGV0cyIpLA0KICAgIHVuYW1lID0gdG91cHBlcihuYW1lKQ0KICApDQpgYGANCiMgQXJlIHlvdSBhYnNvbHV0ZWx5IHN1cmUgdGhhdCB5b3UsIHBlcnNvbmFsbHksIG5lZWQgdG8gaXRlcmF0ZSBvdmVyIHJvd3M/DQoNCmBgYHtyfQ0KZGYgPC0gbmV3X2RmKCkNCnBhc3RlKGRmJG5hbWVbMV0sICJpcyIsIGRmJGFnZVsxXSwgInllYXJzIG9sZCIpDQpgYGANCmBgYHtyfQ0KbiA8LSBucm93KGRmKQ0KcyA8LSB2ZWN0b3IobW9kZSA9ICJjaGFyYWN0ZXIiLCBsZW5ndGggPSBuKQ0KZm9yIChpIGluIHNlcV9sZW4obikpIHsNCiAgc1tpXSA8LSBwYXN0ZShkZiRuYW1lW2ldLCAiaXMiLCBkZiRhZ2VbaV0sICJ5ZWFycyBvbGQiKQ0KfQ0Kcw0KYGBgDQpgYGB7cn0NCnBhc3RlKGRmJG5hbWUsICJpcyIsIGRmJGFnZSwgInllYXJzIG9sZCIpDQpgYGANCmBgYHtyfQ0Kc3RyX2dsdWVfZGF0YShkZiwgIntuYW1lfSBpcyB7YWdlfSB5ZWFycyBvbGQiKQ0KYGBgDQogDQpgYGB7cn0NCmRmICU+JQ0KICBtdXRhdGUoc2VudGVuY2UgPSBzdHJfZ2x1ZSgie25hbWV9IGlzIHthZ2V9IHllYXJzIG9sZCIpKQ0KYGBgDQoNCiMgV29ya2luZyB3aXRoIG5vbi12ZWN0b3JpemVkIGZ1bmN0aW9ucw0KYGBge3J9DQpkZl9saXN0IDwtIGxpc3QoDQogIGlyaXMgPSBoZWFkKGlyaXMsIDIpLA0KICBtdGNhcnMgPSBoZWFkKG10Y2FycywgMykNCikNCmRmX2xpc3QNCmBgYA0KDQpgYGB7cn0NCm5yb3coZGZfbGlzdCkNCmBgYA0KDQpgYGB7cn0NCmxpYnJhcnkocHVycnIpDQoNCm1hcChkZl9saXN0LCBucm93KQ0KYGBgDQoNCmBgYHtyfQ0KbWFwKGRmX2xpc3QsIH4gbnJvdygueCkpDQpgYGANCg0KIyBSb3ctd2lzZSB0aGlua2luZyB2cy4gY29sdW1uLXdpc2UgdGhpbmtpbmcNCmBgYHtyfQ0KeCA8LSBsaXN0KA0KICBsaXN0KG5hbWUgPSAic3VlIiwgbnVtYmVyID0gMSwgdmVnID0gYygib25pb24iLCAiY2Fycm90IikpLA0KICBsaXN0KG5hbWUgPSAiZG91ZyIsIG51bWJlciA9IDIsIHZlZyA9IGMoInBvdGF0byIsICJiZWV0IikpDQopDQp4DQpgYGANCmBgYHtyfQ0KdGliYmxlKA0KICBuYW1lID0gbWFwX2Nocih4LCAibmFtZSIpLA0KICBudW1iZXIgPSBtYXBfZGJsKHgsICJudW1iZXIiKSwNCiAgdmVnID0gbWFwKHgsICJ2ZWciKQ0KKQ0KYGBgDQojIFdvcmsgb24gZ3JvdXBzIG9mIHJvd3MgdmlhIGRwbHlyOjpncm91cF9ieSgpICsgc3VtbWFyaXNlKCkNCmBgYHtyfQ0KYXMudGliYmxlKGlyaXMpDQoNCmBgYA0KDQpgYGB7cn0NCmlyaXMgJT4lDQogIGdyb3VwX2J5KFNwZWNpZXMpICU+JQ0KICBzdW1tYXJpc2UocGxfYXZnID0gbWVhbihQZXRhbC5MZW5ndGgpLCBwd19hdmcgPSBtZWFuKFBldGFsLldpZHRoKSkNCmBgYA0KV2hhdCBpZiB5b3Ugd2FudCB0byByZXR1cm4gc3VtbWFyaWVzIHRoYXQgYXJlIG5vdCBqdXN0IGEgc2luZ2xlIG51bWJlcj8NCmBgYHtyfQ0KaXJpcyAlPiUNCiAgZ3JvdXBfYnkoU3BlY2llcykgJT4lDQogIHN1bW1hcmlzZShwbF9xdGlsZSA9IHF1YW50aWxlKFBldGFsLkxlbmd0aCwgYygwLjI1LCAwLjUsIDAuNzUpKSkNCmBgYA0KYGBge3J9DQppcmlzICU+JQ0KICBncm91cF9ieShTcGVjaWVzKSAlPiUNCiAgc3VtbWFyaXNlKHBsX3F0aWxlID0gbGlzdChxdWFudGlsZShQZXRhbC5MZW5ndGgsIGMoMC4yNSwgMC41LCAwLjc1KSkpKQ0KYGBgDQoNCmBgYHtyfQ0KaXJpcyAlPiUNCiAgZ3JvdXBfYnkoU3BlY2llcykgJT4lDQogIHN1bW1hcmlzZShwbF9xdGlsZSA9IGxpc3QocXVhbnRpbGUoUGV0YWwuTGVuZ3RoLCBjKDAuMjUsIDAuNSwgMC43NSkpKSkgJT4lDQogIG11dGF0ZShwbF9xdGlsZSA9IG1hcChwbF9xdGlsZSwgZW5mcmFtZSwgbmFtZSA9ICJxdWFudGlsZSIpKSAlPiUNCiAgdW5uZXN0KCkgJT4lDQogIG11dGF0ZShxdWFudGlsZSA9IGZhY3RvcihxdWFudGlsZSkpICU+JSANCiAgc3ByZWFkKHF1YW50aWxlLCB2YWx1ZSkNCmBgYA0KIyBSb3ctd2lzZSBTdW1tYXJpZXMNCmBgYHtyfQ0KZGYgPC0gdHJpYmJsZSgNCiAgfiBuYW1lLCB+IHQxLCB+dDIsIH50MywNCiAgIkFiYnkiLCAgICAxLCAgIDIsICAgMywNCiAgIkJlc3MiLCAgICA0LCAgIDUsICAgNiwNCiAgIkNhcmwiLCAgICA3LCAgIDgsICAgOQ0KKQ0KZGYNCmBgYA0KDQpgYGB7cn0NCmRmICU+JQ0KICBtdXRhdGUodF9zdW0gPSByb3dTdW1zKHNlbGVjdF9pZiguLCBpcy5udW1lcmljKSkpDQpgYGANCg0KYGBge3J9DQpkZiAlPiUNCiAgbXV0YXRlKHRfYXZnID0gcm93TWVhbnMoc2VsZWN0KC4sIC1uYW1lKSkpDQpgYGANCiMgVEhJUyENCg0KYGBge3J9DQpkZiAlPiUNCiAgbXV0YXRlKHRfYXZnID0gcm93U3VtcyhzZWxlY3QoLiwgYyh0MSwgdDMpKSkpDQpgYGANCg0K