the_data <- transform( subset( rbind( read.csv('/path/to/data/file1.csv'),
read.csv('/path/to/data/file2.csv')),
variable_a > x),
variable_c = variable_a/variable_b) the_data <- read.csv('/path/to/data/file1.csv') %>%
rbind(read.csv('/path/to/data/file2.csv')) %>%
filter(variable_a > x) %>%
mutate(variable_c = variable_a/variable_b)
You've thrown out a few variations on a theme here, but I'm not sure where you are trying to angle towards. There are a lot of ways to format code, and I can't tell you what works best for you.But this isn't shaking the paradigm of having an initial block of data (here separated a little awkwardly into two files) that is being subjected to a series of functional transformations, which is sorta pipe-like. Being able to talk about this as a 'pipe' is hugely useful, and having a pipe operator really standardises how people can talk about it. In my experience, selling this as a concept to a beginner is a lot easier when it has syntax support so they know they are doing the 'right thing' and get error messages/uncomfortable looking code when they try to cheat. I don't really care how you nest the brackets, if you want to write something that isn't a pipe go with (edit obviously a non-buggy version of...):
for i in 1:nrow(df){
if(df[i,'variable a'] > df[i,'x']) continue;
df[i,'variable ac'] = df[i,'variable_a']/df[i,'variable_b']
}
If someone shows me that and I can tell them to 'go rewrite it using pipe operators, it will be better' they will naturally start seeing that that horrible block of mixed ideas can be separated out into a few basic composable operations, and that is funnily enough easier for a beginner to grasp in my experience teaching people to use R. Plus, they can tell that a statement is going to be a series of composes on top of raw data if they see a pipe operator. This is a useful thing that makes it easier to read the code.Teaching a "paradigm" can be too limiting. Looking at some random tutorial on the web:
"To demonstrate the above advantages of the pipe operator, consider the following example.
round(cos(exp(sin(log10(sqrt(25))))), 2)
# -0.33
"The code above looks messy and it is cumbersome to step through all the different functions and also keep track of the brackets when writing the code.
"The method below uses magrittr‘s pipe (%>%) and makes the function calls easier to understand. sqrt(25) %>%
log10() %>%
sin() %>%
exp() %>%
cos() %>%
round(2)
# -0.33
Really? Do we want to teach people that the code below is so much better than the code above?What do we expect them to do if they find something like
100*exp(cumsum(0.6*diff(log(STOCKS))+0.4*diff(log(BONDS))))
which is a perfectly readable way of calculating the evolution of the value of a 60/40 portfolio of stocks and bonds from the value of each component at each rebalancing date?http://thatdatatho.com/2019/03/13/tutorial-about-magrittrs-p...
It’s easy to find examples of using the pipe in ways that I would consider suboptimal. But that doesn’t affect my thesis that, on average, the use of the pipe leads to more readable code.
I was also initially quite sceptical of the pipe, since it is a fundamentally new syntax for R (although obviously used in many other languages). I think the uptake by a wide variety of people across the R community does suggest there’s something there.
I had a similar experience with Lisp syntax: Clojure's threading macros seem a neat idea but I do actually prefer old-style nesting of function calls.
Maybe my R journey is a bit atypical. I started learning R around the time you created reshape and ggplot and used them extensively. But as the "tidyverse" thing has evolved I have found myself more attracted to "base" R as I've become more familiar with its data structures and functionalities.
df <- rbind(read.csv('/path/to/data/file1.csv'),
read.csv('/path/to/data/file2.csv'))
df <- df[, df$variable_a > x]
df$variable_c <- df$variable_a / df$variable_b
or maybe: df <- subset(rbind(read.csv('/path/to/data/file1.csv'),
read.csv('/path/to/data/file2.csv')),
variable_a > x)
df[,”variable_c”] <- df[,”variable_a”] / df[,”variable_b”]
Whether you think these are badly written pipes or not pipes at all, I don't care. It's good enough for me.