survey |> add(where(startsWith(name, "q"), value * 10))| respondent | region | q1_score | q2_score |
|---|---|---|---|
| 1 | West | 40 | 20 |
| 2 | East | 50 | 50 |
| 3 | West | 30 | 50 |
Writing the same thing for eight columns is eight chances to write it slightly differently. add where takes the same pattern the last two chapters used and one value to apply to each column it matches. Inside that value, value stands for the column being worked on.
survey |> add(where(startsWith(name, "q"), value * 10))| respondent | region | q1_score | q2_score |
|---|---|---|---|
| 1 | West | 40 | 20 |
| 2 | East | 50 | 50 |
| 3 | West | 30 | 50 |
survey >> add(where(name.starts("q"), value * 10))| respondent | region | q1_score | q2_score |
|---|---|---|---|
| 1 | West | 40 | 20 |
| 2 | East | 50 | 50 |
| 3 | West | 30 | 50 |
The matched columns keep their names. That is not a rule this had to invent: add already covers making a column and replacing one, so replacing q1_score with a new q1_score is the ordinary case.
name and value are a pair. One is what the column is called, the other is what it holds, and they are the same two words the reshaping verbs use.
summarize where works the same way and collapses instead.
survey |> summarize(where(endsWith(name, "_score"), average(value)), by = region)| region | q1_score | q2_score |
|---|---|---|
| East | 5.0 | 5.0 |
| West | 3.5 | 3.5 |
survey >> summarize(where(name.ends("_score"), average(value)), by = col.region)| region | q1_score | q2_score |
|---|---|---|
| East | 5.0 | 5.0 |
| West | 3.5 | 3.5 |
dplyr calls this across. Here it needed no verb and one word, because the selector was already there for pick and where already introduces a condition.
Every rule that applies to a value written out by hand applies to this one, because the grammar expands it before checking anything. Asking summarize for something that does not collapse a group is refused, and the message names the column it refused rather than the pattern.
collect(survey |> summarize(where(startsWith(name, "q"), value * 2)))Error:
!
illegal: `summarize` returns one row for each group, so `[q1_score]` has to be a value that spans the group. Wrap it: `total(...)`, `average(...)`, `first(...)`, or count the rows with `row_count()`
|
2 | then summarize where (name starts "q") as (value * 2)
| ^^^^^^^^^
try:
collect(survey >> summarize(where(name.starts("q"), value * 2)))
except GodError as refusal:
print(refusal)
illegal: `summarize` returns one row for each group, so `[q1_score]` has to be a value that spans the group. Wrap it: `total(...)`, `average(...)`, `first(...)`, or count the rows with `row_count()`
|
2 | then summarize where (name starts "q") as (value * 2)
| ^^^^^^^^^
You can see what it expanded to, which is worth doing the first few times. format shows the sentence you wrote; show_as shows the one the grammar settled on.
show_as(survey |> add(where(startsWith(name, "q"), value * 10)), "god")survey
then add [q1_score] as ([q1_score] * 10), [q2_score] as ([q2_score] * 10)
show_as(survey >> add(where(name.starts("q"), value * 10)), "god")survey
then add [q1_score] as ([q1_score] * 10), [q2_score] as ([q2_score] * 10)