Code Monkey home page Code Monkey logo

Comments (17)

hadley avatar hadley commented on June 5, 2024

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.

gaborcsardi avatar gaborcsardi commented on June 5, 2024

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.

gaborcsardi avatar gaborcsardi commented on June 5, 2024

Btw. vpluck fails for empty lists.

from magrittr.

hadley avatar hadley commented on June 5, 2024

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.

smbache avatar smbache commented on June 5, 2024

@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.

gaborcsardi avatar gaborcsardi commented on June 5, 2024

@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.

piccolbo avatar piccolbo commented on June 5, 2024

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.

gaborcsardi avatar gaborcsardi commented on June 5, 2024

@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 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.

ctbrown avatar ctbrown commented on June 5, 2024

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.

piccolbo avatar piccolbo commented on June 5, 2024

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 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.


Reply to this email directly or view it on GitHub
#21 (comment).

from magrittr.

gaborcsardi avatar gaborcsardi commented on June 5, 2024

@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.

piccolbo avatar piccolbo commented on June 5, 2024

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.

gaborcsardi avatar gaborcsardi commented on June 5, 2024

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.

smbache avatar smbache commented on June 5, 2024

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.

gaborcsardi avatar gaborcsardi commented on June 5, 2024

@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.

smbache avatar smbache commented on June 5, 2024

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.

gaborcsardi avatar gaborcsardi commented on June 5, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.