I don't understand why purrr::transpose issues an error after the pipe operator.
This isn"t the case with other functions like purrr::map.
See example below:
library(purrr)
# Works
identical(mtcars %>% map(~{.x}), mtcars %>% purrr::map(~{.x}))
# [1] TRUE
# Works
mtcars %>% transpose
# Doesn't work
mtcars %>% purrr::transpose
#Error in .::purrr : unused argument (transpose)
It is possible I have misunderstood the namespace operator please correct me if so however this is what I believe the reason to be.
I believe this is an issue where the namespace notation actually acts as an infix operator ::. This means that the function call it is trying to use is:
`::`(mtcars, purrr, transpose)
The error here occurs as the namespace infix operator can only accept two arguments: the package name and the function from the package.
This isn't expected by the user as we would want to be able to use functions from external namespaces with the pipe operator. This is because the code is confused as to what the function attempting to be called is and so it finds the first function it can (in this case ::).
The solution to this is to use brackets to note that transpose is the function or that purrr::transpose should be evaluated first. We can do this with the following code:
# purrr::transpose is the function
mtcars %>% purrr::transpose()
# Evaluate this block as the expression of the function
mtcars %>% (purrr::transpose)
Related
I tried searching for this but couldn't find any similar questions. Let's say, for the sake of a simple example, I want to do the following using dplyr's pipe %>%.
c(1,3,5) %>% ls() %>% mean()
Setting aside what the use case would be for a pipeline like this, how can I call a function "mid-pipeline" that doesn't need any inputs coming from the left-hand side and just pass them along to the next function in the pipeline? Basically, I want to put an "intermission" or "interruption" of sorts into my pipeline, let that function do its thing, and then continue on my merry way. Obviously, the above doesn't actually work, and I know the T pipe %T>% also won't be of use here because it still expects the middle function to need inputs coming from the lhs. Are there options here shy of assigning intermediate objects and restarting the pipeline?
With the ‘magrittr’ pipe operator you can put an operand inside {…} to prevent automatic argument substitution:
c(1,3,5) %>% {ls()} %>% mean()
# NA
# Warning message:
# In mean.default(.) : argument is not numeric or logical: returning NA
… but of course this serves no useful purpose.
Incidentally, ls() inside a pipeline is executed in its own environment rather than the calling environment so its use here is even less useful. But a different function that returned a sensible value could be used, e.g.:
c(1,3,5) %>% {rnorm(10)} %>% mean()
# [1] -0.01068046
Or, if you intended for the left-hand side to be passed on, skipping the intermediate ls(), you could do the following:
c(1,3,5) %>% {ls(); .} %>% mean()
# [1] 3
… again, using ls() here won’t be meaningful but some other function that has a side-effect would work.
You could define an auxilliary function like this, that takes an argument it doesn't use in order to allow it to fit in the pipe:
ls_return_x <- function(x){
print(ls())
x
}
c(1,3,5) %>% ls() %>% mean()
Note, the ls() call in this example will print the objects in the environment within the ls_return_x() function. Check out the help page for ls() if you want to print the environment from the global environment.
I don't know if there is an inbuilt function but you could certainly create a helper function for this
> callfun <- function(x, fun){fun(); return(x)}
> c(1, 3, 5) %>% callfun(fun = ls) %>% mean()
# [1] 3
I don't really see the point but hey - it's your life.
Is it possible to combine the forward pipe operator with an anonymous function?
If so then how can i go about it?
I get that the basic idea is to pass arguments in a sequential manner for the functions to execute.Like below,first the anonymous function calculates the sum then passes it on to the factorial function.
How can I do the same
This is what I am trying to execute using the forward-pipe operator-
calculate <- function(func,d)
{
func(d)
}
factorial(calculate(function(x){x+1},7)) # function x is the anonymous function
My code using the forward-pipe operator-
7 %>% calculate(function(x){x+1}) %>% fact()
the expected result is 40320, but it results in
Error in func(d) : could not find function "func"
Another option is to call calculate's arguments explicitly using name
7 %>% calculate(func=function(x){x+1}) %>% factorial()
When you use %>% the argument (in your case 7) is plugged in as the first argument of the preceeding function. Thus, 7 %>% calculate(function(x){x+1}) actually evaluates to calculate(7, function(x){x+1}).
You can fix this with
7 %>% calculate(function(x){x+1}, .) %>% factorial()
or with named arguments as then 7 is matched to the remaining argument.
I'm struggling to pipe stuff to another argument inside the function filter from dplyr using %>% margritr.
I would assume that this should work:
library(dplyr)
library(margritr)
d <- data.frame(a=c(1,2,3),b=c(4,5,6))
c(2,2) %>% filter(d, a %in% .)
But I get this:
# Error in UseMethod("filter_") :
# no applicable method for 'filter_' applied to an object of class "c('double', 'numeric')"
I would expect it to work in the same way as this:
filter(d, a %in% c(2,2))
# a b
# 1 2 5
What am I doing wrong?
The pipe is designed to compose the function around its first argument when you pass it. When you want to circumvent this behavior, you can generate an anonymous environment that is more flexible. You do this with curly braces, just like when you're writing a function.
5 %>%
{filter(iris, Sepal.Length == .)}
For why this works, writing {somefunctions(x, y)} is equivalent to writing function(...) {somefunctions(x, y)}. So the function above ignores its arguments, but just evaluates the variables in its environment. The . pronoun is defined for it by the pipe, and it searches for other variables (like iris) in the global environment.
By default it will pipe to the first argument. The only way around it is to name the first arg explicitly:
c(2,2) %>%
filter(.data = d, a %in% .)
but looks like this doesn't work very well:
a b
1 2 5
Warning message:
In (~.) & (~a %in% .) :
longer object length is not a multiple of shorter object length
P.S. you don't need to load magrittr explicitly as %>% is already in dplyr
I'm trying to make a function that subsets and mutates data with dplyr commands. My fake data is like this:
newTest_rv <- data.frame(is_op=c(rep(0,6),rep(1,4)),
has_click=c(0,0,1,1,1,1,0,0,1,1),
num_pimp=c(3,5,1,2,3,5,2,5,3,5),
freq = c(rep(1,5),5,1,2,1,2))
And my function is like this:
reweight <- function(data, conds){
require(dplyr)
require(lazyeval)
data %>%
filter_(lazy(conds)) %>%
group_by(num_pimp) %>%
mutate_(lazy(new_num) = lazy(num_pimp) - lazy(sum(freq[lazy(!conds)]))) %>%
mutate(new_weight=freq*(1/new_num)) %>%
ungroup()
}
> reweight(newTest_rv, is_op==0)
The non-standard evaluation with the conditional statement "is_op==0" seems to work in other places but not in the subset within a group "lazy(sum(freq[lazy(!conds)]))". Is there any way I can circumvent this problem?
Thank you!
It looks like you went a bit overboard with the lazys. The lazy() function creates a lazy object which basically delays evaluation of an expression. You can't just compose standard expressions and lazy expression. Generally you combine them via lazyeval's interp() function. I think what you want is
mutate_(new_num = interp(~num_pimp - sum(freq[!(x)]), x=lazy(conds)))
Here we use interp() to take a standard expression (in this case one that uses the formula syntax) and insert the lazy expression as a subsetting vector.
I have seen the use of %>% (percent greater than percent) function in some packages like dplyr and rvest. What does it mean? Is it a way to write closure blocks in R?
%...% operators
%>% has no builtin meaning but the user (or a package) is free to define operators of the form %whatever% in any way they like. For example, this function will return a string consisting of its left argument followed by a comma and space and then it's right argument.
"%,%" <- function(x, y) paste0(x, ", ", y)
# test run
"Hello" %,% "World"
## [1] "Hello, World"
The base of R provides %*% (matrix mulitiplication), %/% (integer division), %in% (is lhs a component of the rhs?), %o% (outer product) and %x% (kronecker product). It is not clear whether %% falls in this category or not but it represents modulo.
expm The R package, expm, defines a matrix power operator %^%. For an example see Matrix power in R .
operators The operators R package has defined a large number of such operators such as %!in% (for not %in%). See http://cran.r-project.org/web/packages/operators/operators.pdf
igraph This package defines %--% , %->% and %<-% to select edges.
lubridate This package defines %m+% and %m-% to add and subtract months and %--% to define an interval. igraph also defines %--% .
Pipes
magrittr In the case of %>% the magrittr R package has defined it as discussed in the magrittr vignette. See http://cran.r-project.org/web/packages/magrittr/vignettes/magrittr.html
magittr has also defined a number of other such operators too. See the Additional Pipe Operators section of the prior link which discusses %T>%, %<>% and %$% and http://cran.r-project.org/web/packages/magrittr/magrittr.pdf for even more details.
dplyr The dplyr R package used to define a %.% operator which is similar; however, it has been deprecated and dplyr now recommends that users use %>% which dplyr imports from magrittr and makes available to the dplyr user. As David Arenburg has mentioned in the comments this SO question discusses the differences between it and magrittr's %>% : Differences between %.% (dplyr) and %>% (magrittr)
pipeR The R package, pipeR, defines a %>>% operator that is similar to magrittr's %>% and can be used as an alternative to it. See http://renkun.me/pipeR-tutorial/
The pipeR package also has defined a number of other such operators too. See: http://cran.r-project.org/web/packages/pipeR/pipeR.pdf
postlogic The postlogic package defined %if% and %unless% operators.
wrapr The R package, wrapr, defines a dot pipe %.>% that is an explicit version of %>% in that it does not do implicit insertion of arguments but only substitutes explicit uses of dot on the right hand side. This can be considered as another alternative to %>%. See https://winvector.github.io/wrapr/articles/dot_pipe.html
Bizarro pipe. This is not really a pipe but rather some clever base syntax to work in a way similar to pipes without actually using pipes. It is discussed in http://www.win-vector.com/blog/2017/01/using-the-bizarro-pipe-to-debug-magrittr-pipelines-in-r/ The idea is that instead of writing:
1:8 %>% sum %>% sqrt
## [1] 6
one writes the following. In this case we explicitly use dot rather than eliding the dot argument and end each component of the pipeline with an assignment to the variable whose name is dot (.) . We follow that with a semicolon.
1:8 ->.; sum(.) ->.; sqrt(.)
## [1] 6
Update Added info on expm package and simplified example at top. Added postlogic package.
Update 2 The development version of R has defined a |> pipe. Unlike magrittr's %>% it can only substitute into the first argument of the right hand side. Although limited, it works via syntax transformation so it has no performance impact.
%>% is similar to pipe in Unix. For example, in
a <- combined_data_set %>% group_by(Outlet_Identifier) %>% tally()
the output of combined_data_set will go into group_by and its output will go into tally, then the final output is assigned to a.
This gives you handy and easy way to use functions in series without creating variables and storing intermediate values.
My understanding after reading the link offered by G.Grothendieck is that %>% is an operator that pipes functions. This helps readability and productivity as it's easier to follow the flow of multiple functions through these pipes than going backwards when multiple function are nested.
The R packages dplyr and sf import the operator %>% from the R package magrittr.
Help is available by using the following command:
?'%>%'
Of course the package must be loaded before by using e.g.
library(sf)
The documentation of the magrittr forward-pipe operator gives a good example:
When functions require only one argument, x %>% f is equivalent to f(x)
Another usage for %---% is the use of %<-% which means a multi-assignment operator for example:
session <- function(){
x <- 1
y <- 2
z <- y + x
list(x,y,z)
}
c(var1,var2,result) %<-% session()
I don't know much about it but I have seen it in one case study during the study of Multivariate Normal Distribution in R in my college
suppose you have a data frame in a variable called "df_gather" and you want to pipe it into a ggplot then you can use that %>%
EG:
df_gather %>% ggplot(aes(x = Value, fill = Variable, color = Variable))+
geom_density(alpha = 0.3)+ggtitle('Distibution of X')