It results in code that more closely resembles executed order of operations (e.g. filter -> mutate -> group -> summarize). Context is also key: it's most often used for data processing pipelines in specific analytical scripts or literate-code documents - less so used when defining generalizable/testable functions in packages (again, just a personal perspective - YMMV of course)
https://clojure.org/reference/transducers
https://stackoverflow.com/questions/26317325/can-someone-exp...
Let's say I have a table called dat.
dat %>%
filter(col_a == 'Good') %>%
group_by(col_b) %>%
summarize(n = n(), sum_c = sum(col_c))
To do this in traditional R, I would have to: dat <- dat[dat$col_a == 'Good']
dat_n <- aggregate(col_a ~ col_b, dat, length)
dat_sum <- aggregate(col_c ~ col_b, dat, sum)
merge(dat_n, dat_sum, by = "col_b")
I think the piped version is more readable. At least there are less variable to track. dat[col_a == 'Good', .(Length = .N, Sum = sum(col_c)), col_b]There also isn't any reason why other implementations of pipes have to do buffered byte read/writes, passing objects is perfectly acceptable.
The structurally distinguishing aspect of a pipe-and-filter style is that the individual processing elements don't "return" to their "caller", but rather pass their result on to the next processing element. Without involving the caller.
Actually it makes R scripts much easier to grasp. It prevents the abusive usage of brackets, and it makes the data transformation flow more obvious.
f(a, g(h(x), b))
h(x) %>% g(b) %>% f(a, .)
"Thus, programs must be written for people to read, and only incidentally for machines to execute."https://cran.r-project.org/web/packages/rlang/vignettes/tidy...
a = "foo"
a = "bar"
reusing variables is silly.