You're helping me to clarify where I am, and that is good. I quite like piping with magrittr and the "verbs" of dplyr and I use them all the time now. I have not read about "tidy," and I suppose that I should. What I understand now is that the "." following a pipe refers only to he object that has been passed by the pipe, but that it doesn't permit applying any array selection to the object or allow the object to be passed to an internal function within the function following the pipe. I'm pretty sure that this is a scope issue. Let me explain one of my frustrations.
I am primarily a statistician, not a programmer. I deal with a lot of data sets in which columns contain only numbers, but that may need to be referred to in some situations as factors and in others as numbers. (E.g., data where the number represents one of a number of conditions, but where the conditions may be graded monotonically.) So I don't want either to change the column from numeric to factor, and I don't want to add a new column with the value as a factor. As a convenience, I have created the function facsum(x) summary(as.factor(x). This works fine on a named table. :
facsum <- function(x) summary(as.factor(x))
facsum(iris$Petal.Length)
1 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.9 3 3.3 3.5 3.6 3.7 3.8 3.9 4 4.1 4.2
1 1 2 7 13 13 7 4 2 1 2 2 1 1 1 3 5 3 4
4.3 4.4 4.5 4.6 4.7 4.8 4.9 5 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9 6 6.1
2 4 8 3 5 4 5 4 8 2 2 2 3 6 3 3 2 2 3
6.3 6.4 6.6 6.7 6.9
1 1 1 2 1
But it doesn't work after I have manipulated iris using dplyr and magrittr:
iris %>% filter(Species == 'setosa') %>% facsum(Petal.Length)
Error in facsum(., Petal.Length) : unused argument (Petal.Length)
Adding the with() fixes this (though I acknowledge that this is a real kludge):
iris %>% filter(Species == 'setosa') %>% with(facsum(Petal.Length))
1 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.9
1 1 2 7 13 13 7 4 2
The same is true whenever I want to apply any function after the pipe that needs to pass the piped object to an internal function. With() solves this problem.
iris %>% filter(Species == 'setosa') %>% sum(Petal.Length < 0.2)
Error in function_list[k] : object 'Petal.Length' not found
iris %>% filter(Species == 'setosa') %>% with(sum(Petal.Length < 0.2))
[1] 0
I agree that your "tidy" is probably a better way to deal with row and column selection, but it would be nice to be able to use functions that have to call functions after a pipe. Is there a better way than with() to do this?