Closed sfd99 closed 4 years ago
@sfd99 I can answer this one.
The pipe currently interprets dist
as a separate argument to mean, and the object does not exist. What you want to do is subset the object to get only that column. Mean accepts only a numeric vector as an argument, so you must coerce the data to match.
Here are two solutions, both being sort of messy:
# Option 1
cars %.% {
head(2)
subset(select = 'dist')
unlist()
mean()
}
# Option 2
cars %.% {
head(2)
`[[`("dist")
mean()
}
Thanks Branson for the quick reply.
Yes, you explain the problem very clearly.
As I understand it, (in my limited knowledge), some R BASE functions like mean(), plot(), cor(), only accept a vector of values as input. Fine.
But any %>% pipe, before mean() will "feed" mean() with a dataframe structure. mean() will gasp!.
So, this will fail:
cars %>%
head(2) %>%
mean(dist)
[1] NA
Warning message: In mean.default(., dist) : argument is not numeric or logical: returning NA
But...this will work: YAY!
cars %>%
head(2) %$%
mean(dist)
[1] 6
Seems the special %$% pipe, (part of the standard pipes family, originally f/ magrittr pkg), “explodes out" all the variables in a data frame so that you can refer to them explicitly.
So, the %$% pipe is Super-useful when working with many base R functions! ...like mean(), plot(), cor(), etc... which need a vector of values not a DF, to work properly.
Hope Antoine can add this %$% functionality to his great %.% pipe in the nakedpipe pkg!. This way, we'll be able to use the %.% pipe w/ any base-R functions, too!.
That would be fantastic!!!...
I'm excited to have issues to solve here :), and just as much to have other people interacting, thank you both so much.
@bransonf is right, I'd personally probably use his 2nd solution, or use dplyr::pull()
instead of [[
(or purrr::pluck()
with lists), or use with()
as shown below. Note that you can write .[["dist"]]
rather than `[[`("dist")
I'll add a nuance, @bransonf said dist
didn't exist but it does, it's a function from the package stats, the error would be different if it didn't.
mean(dist)
is changed internally to mean(., dist)
, that's why you see the dot in the error message, the dot is the result of the previous call, but dist
is fed to the second argument of mean.default
, which is trim
, trim
receives a function where it expected a numeric, hence the error.
magrittr indeed has %$%
to solve the problem, but %$%
is really just with()
in infix form :
library(magrittr)
cars %>% head(2) %$% mean(dist)
#> [1] 6
cars %>% head(2) %>% with(mean(dist))
#> [1] 6
# let's make our own
`%$$%` <- with
cars %>% head(2) %$$% mean(dist)
#> [1] 6
Using nakedpipe we can use with()
in the same way :
library(nakedpipe)
cars %.% {
head(2)
with(mean(dist))
}
#> [1] 6
Or use {}
as in magrittr to force dots to be explicit (not insert them in first position by default)
cars %.% {
head(2)
{mean(.$dist)}
}
#> [1] 6
Or use %..%
so all dots need to be explicit, then no need for {}
but we need to use the dot in the head()
call too.
cars %..% {
head(.,2)
mean(.$dist)
}
#> [1] 6
So I am not sure if a new syntax is needed here (and I don't know what it would be), but I'll add your example to the doc.
Another idea :
`%with%` <- with
cars %.% {
head(2)
. %with% mean(dist)
}
#> [1] 6
All good alternative ideas, Antoine!.
As a user, I like your solution:
cars %.% {
head(2)
with(mean(dist))
}
[1] 6
because it's cleaner and simpler than the other valid solutions.
It follows +better the "spirit" of your nakedpipe pkg.: = write less code and do more!...
The ideal would be if you could "incorporate" the functionality of the %$% pipe, (as needed by certain R-base functions like: mean, plot, cor...).
This way, the end user does not need to remember extra special syntax.
Even if one R command inside the { ... } is R-base and expects a vector of values, nakedpipe would detect the situation and handle it!.
That's the beauty of the syntax and easy flow of nakedpipe, simple and elegant!:
DF %.% { R command 1 (R-base or not) R command 2 (R-base or not) .... }
to make the life of the end user simpler.
So, Antoine, maybe when you are at sea, on your ship, the idea will suddenly come to you how to do this... :-)
This old thread has been automatically locked. If you think you have found something related to this, please open a new issue and link to this old issue if necessary.
Hi Antoine,
Your nakedpipe pkg. is really GREAT!. Love it.
Question:
When I try:
cars %.% { head(2)
mean(dist) }
I get:
[1] NA Warning message: In mean.default(., dist) : argument is not numeric or logical: returning NA
What am I missing?. I really, really want to use the %.% pipe!. :-)
Merci / Thanks! sfd99 San Francisco Rstudio/Ubuntu Linux