21  Choosing by the shape of a name

When a table has thirty columns and you want the eight that begin with q, naming them is tedious and goes stale the moment a ninth arrives. pick where takes a question about a column’s name instead.

survey <- data.frame(
  respondent = 1:3,
  q1_score   = c(4, 5, 3),
  q2_score   = c(2, 5, 5),
  region     = c("West", "East", "West"),
  stringsAsFactors = FALSE
)

survey |> pick(where(startsWith(name, "q")))
q1_score q2_score
4 2
5 5
3 5
survey = pd.DataFrame({
    "respondent": [1, 2, 3],
    "q1_score":   [4, 5, 3],
    "q2_score":   [2, 5, 5],
    "region":     ["West", "East", "West"],
})

survey >> pick(where(name.starts("q")))
q1_score q2_score
4 2
5 5
3 5

name is the word for whichever column is being considered. There are three tests you can ask about it, starts, ends and contains, and they join with and, or and not like any other condition.

survey |> pick(where(endsWith(name, "_score") | name == "respondent"))
respondent q1_score q2_score
1 4 2
2 5 5
3 3 5
survey >> pick(where(name.ends("_score") | (name == "respondent")))
respondent q1_score q2_score
1 4 2
2 5 5
3 3 5

If no column’s name matches, that is refused rather than handing back a table with no columns at all.

collect(survey |> pick(where(startsWith(name, "zzz"))))
Error:
! 
illegal: no column's name matches that, so this would leave the table with no columns. It has: respondent, q1_score, q2_score, region
  |
2 |   then pick where (name starts "zzz")
  |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
try:
    collect(survey >> pick(where(name.starts("zzz"))))
except GodError as refusal:
    print(refusal)

illegal: no column's name matches that, so this would leave the table with no columns. It has: respondent, q1_score, q2_score, region
  |
2 |   then pick where (name starts "zzz")
  |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^