Comments (17)
An alternative approach is:
pluck <- function(x, i) lapply(x, "[[", i)
vpluck <- function(x, i) vapply(x, "[[", i, FUN.VALUE = x[[1]][[i]])
filenames <- files %>% vpluck("metadata") %>% vpluck(".path") %>% no_dup_names
I think adding additional operators is unlikely to make code easier to read.
from magrittr.
Yes, that's actually much better for the specific example.
The thing is, selecting an element is just one thing you can do in a lapply. In general you can have.
data %>%
lapply(lambda(x -> transform(x))) %>%
lapply(lambda(x -> transform2(x))) %>%
lapply(lambda(x -> transform3(x)))
and with the new operator you could write this as
data %[>%
transform %[>%
transform2 %[>%
transform3
which looks much better to me. But arguably, this is also a matter of taste. I probably would not want to write a pluck
equivalent to each transform*
function.
from magrittr.
Btw. vpluck
fails for empty lists.
from magrittr.
But can't you write that as
data %>%
lapply(transform, .) %>%
lapply(transform2, .) %>%
lapply(transform3, .)
?
Using %[>%
is certainly terser, but I think the more of this sort of operator you introduce, the more background knowledge people will need to understand your code. I think %>%
is ok because it's going to be everywhere (tidyr, dplyr, ggvis), but %[>%
will be much rarer (also I find it really hard to type).
from magrittr.
@gaborcsardi quick side note: the lambda syntax has changed and uses ~
rather than ->
since the latter was very upsetting for R CMD Check
from magrittr.
@hadley: you mean
data %>%
lapply(transform) %>%
lapply(transform2) %>%
lapply(transform3)
? Yes, in this case I can do that. The problem with this is still that I cannot use anonymous functions easily, without the lambda syntax above. I think anonymous functions go well together with *apply
.
Yes, it is not easy to type, maybe %L>%
is easier, I thought %[>%
looked better.
from magrittr.
so if you define
L = lapply
you can have
data %>%
L(transform) %>%
L(transform2) %>%
L(transform3) %>%
This only has 6 parens as additional noise compared to Gabor's very
elegant, in my opinion, form. Since "elegance" is subjective, my criteria
for APIs are conciseness and locality (aka semantically related things
should be nearby syntactically). I don't see an objective case for Gabor's
operator under my own criteria, but I still kind of like it instinctively.
Maybe if Stefan doesn't accept this suggestion, we could have a
magrittr-extra or some such to throw some things against the wall and see
what sticks. It's hard to finally discard a new form based on one, albeit
general, example.
On Fri, Jun 27, 2014 at 7:32 AM, Gabor Csardi [email protected]
wrote:
@hadley https://github.com/hadley: you mean
data %>%
lapply(transform) %>%
lapply(transform2) %>%
lapply(transform3)? Yes, in this case I can do that. The problem with this is still that I
cannot use anonymous functions easily, without the lambda syntax above. I
think anonymous functions go well together with *apply.Yes, it is not easy to type, maybe %L>% is easier, I thought %[>% looked
better.—
Reply to this email directly or view it on GitHub
#21 (comment).
from magrittr.
yes, it is 6 extra characters in this case, but if you want to use anonymous functions, then you arrive back to my original post. E.g. you need to write
newdata <- data %>%
lapply(lambda(x ~ unique(as.character(x))) %>%
sapply(lambda(x ~ paste(x, collapse="-"))) %>%
make.unique()
instead of
newdata <- data %[>%
as.character() %[>%
unique() %[[>%
paste(collapse="-") %[>%
make.unique()
Or course you could write the first one with a single sapply
, but then you lose the essence of piping.
from magrittr.
For what it's worth, I think that @piccolbo has a pretty good compromise, that is to keep some experimental behaviors in a magrittr.extra
package. What @gaborcsardi is proposing looks good, but I share @hadley's concerns that the introduction of new operators is problematic. %>%
conflicts with the same operator ,different behaviors from the operators
package, for instance.
from magrittr.
Hmmm, let me try
L = lapply
S = sapply
newdata <- data %>%
L(as.character) %>%
L(unique) %>%
S(paste, collapse="-") %>%
L(make.unique)
I haven't tried it, I hope it's equivalent. It seems to me you are
adding the lambdas when there isn't really is a need. Maybe you need a
lambda with a more complex body to strengthen your argument.
On Fri, Jun 27, 2014 at 10:17 AM, Gabor Csardi [email protected]
wrote:
@piccolbo https://github.com/piccolbo:
yes, it is 6 extra characters in this case, but if you want to use
anonymous functions, then you arrive back to my original post. E.g. you
need to writenewdata <- data %>%
lapply(lambda(x ~ unique(as.character(x))) %>%
sapply(lambda(x ~ paste(x, collapse="-"))) %>%
make.unique()instead of
newdata <- data %[>%
as.character() %[>%
unique() %[[>%
paste(collapse="-") %[>%
make.unique()Or course you could write the first one with a single sapply, but then
you lose the essence of piping.—
Reply to this email directly or view it on GitHub
#21 (comment).
from magrittr.
@ctbrown: I would not worry much about name clashes, they are bound to happen as we'll have more and bigger R packages. R should provide the mechanisms to handle them, e.g. importing a function under a different name would be great. But this is not the package developers' problem, imho.
from magrittr.
Chris, there's always a competition for shorter idioms. As guy Steele said
"there are only so many concise notations to go around". I am not sure we
should check all existing packages for previous uses of a symbol. That
would freeze change for good. I for one had never heard of operators
before. I still like %|% better because of Unix, but Hadley told me "it's
too late for that" if that means anything to you.
On Fri, Jun 27, 2014 at 10:29 AM, Christopher Brown <
[email protected]> wrote:
For what it's worth, I think that @piccolbo https://github.com/piccolbo
has a pretty good compromise, that is to keep some experimental behaviors
in a magrittr.extra package. What @gaborcsardi
https://github.com/gaborcsardi is proposing looks good, but I share
@hadley https://github.com/hadley's concerns that the introduction of
new operators is problematic. %>% conflicts with the same operator
,different behaviors from the operators package, for instance.—
Reply to this email directly or view it on GitHub
#21 (comment).
from magrittr.
Hmmm, maybe actually you are right, and it is not worth doing this. At least if I cannot come up with a real example, then it is unlikely that this would be very useful. :)
from magrittr.
I too have spent some time wondering whether one should somehow "interface" the *apply functions, but never found something I was satisfied with to an extent where it outweighs the "cost/concern" Hadley mentioned.
On the other hand, although also only experimental, one may use the compose operator/function discussed in Issue 18. Now, I haven't gone through your examples in detail, but here is another one which illustrate how one can use it with sapply:
errors <-
dir("logdir", full.names = TRUE) %>%
sapply(
readLines(.) %,%
grep("Error", ., value = TRUE) %,%
paste(., collapse = "\n")
) %>%
paste(collapse = "\n")
Suppose, you want to use the input from one step in another, say add the filename from the first step above, to the last, then one can name it as so:
errors <-
dir("logdir", full.names = TRUE) %>%
sapply(
(nm ~ readLines(nm)) %,%
grep("Error", ., value = TRUE) %,%
paste(c(nm, .), collapse = "\n")
) %>%
paste(collapse = "\n")
The main difference between %>%
and %,%
is that the former expects a value as LHS, whereas the latter expects expressions/functions as both LHS and RHS. Each expression can be a named function, or an expression where .
is default input name, which can be changed as illustrated, and reused in any step after.
The %,%
operator is therefore also quite useful to compose parts of a pipe-chain, which can be re-used in a later chain. Just remember that one explicitely has to place the input.
from magrittr.
@smbache: Hmmm, to be honest, this is a bit hard to read for me, because I need to think about bigger blocks, at two levels. I get it, that it is reusable, but one could just define a function then, and that is reusable as well, no?
Anyway, I think I am convinced now, that there is no real problem to solve here. :)
from magrittr.
Fair enough. Right, you could write a function, this is just shorter and slightly more pipish, and avoiding a few (
and {
here and there.
from magrittr.
I will just close this now, I think we discussed it, and I accept that it does not make much sense.
from magrittr.
Related Issues (20)
- Feature request: Assignment expression operator HOT 1
- Move `master` branch to `main` HOT 1
- `magrittr::freduce()` doesn't support lambda functions HOT 4
- Add warning when piped object overwrites keyword arguments when not used as first argument HOT 1
- Inconsistent assign() behavior in simple piping with Magrittr HOT 1
- Bug: Rstudio completion with "mrgmod" S4 class object HOT 4
- Feature: Function to create functional sequences HOT 1
- Suggest alias for `Encoding<-` HOT 1
- Hartmann pipelines HOT 3
- Magrittr Logo HOT 1
- difference in performance HOT 2
- Different results using pipes HOT 2
- introspection HOT 2
- magrittr upkeep 2023
- Add function not behaving correctly when being fed an expression
- Pipe doesn't work in basic round function HOT 1
- Question: magrittr's pipes not hyperlinked in docs, why not?
- Question: UN or UNE pipe? HOT 1
- Assignment pipe `%<>%` breaks if R-native `|>` pipes used in chain instead of magrittr-native pipes `%>%` HOT 1
- How to quote magrittr library/package in function call: `magrittr::%<>%` doesn't work HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from magrittr.