[R] Using ddply within a function by argument transfer

Joshua Wiley jwiley.psych at gmail.com
Mon Mar 5 01:46:49 CET 2012


Well, the only part that did not work nicely was the inside function.
So you could still probably lean on ddply() for much of the work and
just append the output of your function to the ddply results or
something like that.

You might also try to think about your problem in a different way.
Sometimes it is not your problem that is intractable but your approach
to solving it, and sometimes what works nicely when typed directly is
not the best way for a function.  There is a famous quote that
captures that idea:

If the answer is parse() you should usually rethink the question.
   -- Thomas Lumley
      R-help (February 2005)

Cheers,

Josh

On Sun, Mar 4, 2012 at 3:28 PM, Fredrik Karlsson <dargosch at gmail.com> wrote:
> Hi Joshua,
>
> Yes, sorry - I attached an .rda file - maybe it was squashed.
> Anyway, yes, I agree with you that the function in the present state would
> not be of very much help to an end user (and your right in thinking that
> this is not the end implementation of the function, just an example). I too
> cannot find a combination of candidate functions that work.
> What I need is the ability for the user to specify the columns in data to be
> processed by ddply and the data frame itself. So far I have not been able to
> do this using ddply - I guess I'll have to roll my own using for loops and
> data frame subsetting or something similar.
>
> Thank you for trying!
>
> /Fredrik
>
> On Sun, Mar 4, 2012 at 12:50 PM, Joshua Wiley <jwiley.psych at gmail.com>
> wrote:
>>
>> Hi,
>>
>> Still no data (either not attached or a format the mail server
>> scrubs), but I made some up.  ddply seems to be a bit tricky in that
>> it holds off evaluating its arguments.  I honestly am not sure how to
>> get around that---no amount of fancy footwork with eval() or quote()
>> is going to change the internals of ddply.  The easiest approach seems
>> to be to change the call to it in the first place.  You cannot do this
>> by passing arguments, but you can by using subsitute() to have your
>> test function construct and then evaluate the ddply() call.  Here is a
>> working example:
>>
>> require(plyr)
>>
>> pb <- data.frame(Type = sample(6, 30, TRUE),
>>                 Sex = sample(0:1, 30, TRUE),
>>                 Speaker = sample(3, 30, TRUE),
>>                 F1 = rnorm(30))
>>
>> insidefun <- function(x){
>>  return(x+1)
>> }
>>
>> testfun <- function(data, factors, x, fun = quote(summarize)) {
>>  arglist <- list(data = data, factors = as.quoted(factors), fun = fun, x =
>> x)
>>  myd <- substitute(ddply(.data=data,
>>    .variables=factors, .fun = fun, norm = x), arglist)
>>  out <- eval(myd)
>>  return(out)
>> }
>>
>> testfun(pb, c("Type","Sex","Speaker"), x = quote(insidefun(F1)))
>>
>> By the way, in its present state, this is essentially a painfully
>> complex wrapper to ddply and your code would probably be less buggy
>> and easier to understand just using ddply, but presumably you are
>> planning to have some other stuff go on in the real testfun().
>>
>> Cheers,
>>
>> Josh
>>
>> On Sun, Mar 4, 2012 at 9:06 AM, Fredrik Karlsson <dargosch at gmail.com>
>> wrote:
>> > Hi,
>> >
>> > Sorry all - I will provide a reproducable version of this. I am still
>> > seeing the same problem - maybe it is due to me having to use summarize?
>> > Anyway, here is an example (using the data set attached):
>> >
>> > Two test functions:
>> >
>> > insidefun <- function(x){
>> >
>> >  return(x+1)
>> > }
>> >
>> > testfun <- function(data,factors,x){
>> >
>> >  datOrig <- ddply(.data=data,
>> >                   .variables=as.quoted(factors),
>> >                   .fun=summarize,
>> >                   norm=insidefun(x)
>> >                   )
>> >
>> > }
>> >
>> >> testfun(pb,c("Type","Sex","Speaker"),F1)
>> > Error in insidefun(x) : object 'x' not found
>> >
>> > Now, if I call ddply directly, it works:
>> >
>> >> head(ddply(pb,.(Type,Sex,Speaker),summarize,norm=insidefun(F1)),4)
>> >  Type Sex Speaker norm
>> > 1    c   f      62  461
>> > 2    c   f      62  401
>> > 3    c   f      62  601
>> > 4    c   f      62  611
>> >
>> > I'm sure I'm doing something stupid - and of course I see that the ddply
>> > call
>> > inside the function will have to do some processing in order to get the
>> > arguments in the right mode/class - but I don't know how.
>> >
>> > /Fredrik
>> >
>> >
>> >
>> >
>> > On Sun, Mar 4, 2012 at 6:44 AM, David Winsemius
>> > <dwinsemius at comcast.net>wrote:
>> >
>> >>
>> >> On Mar 4, 2012, at 12:20 AM, Fredrik Karlsson wrote:
>> >>
>> >>  Hi Michael,
>> >>>
>> >>> No, sorry - that is neither the problem or the solution.
>> >>>
>> >>>  suspicious.vowels(pb,c("Type",**"Sex","Vowel"),F1,F2)
>> >>>>
>> >>> Error in mean(y, na.rm = na.rm) : object 'f1' not found
>> >>>
>> >>>
>> >> Obviously you have still failed to offer reproducible code to go along
>> >> wiht your questions, but I would observe that in R that f1 is NOT going
>> >> to
>> >> equal F1.
>> >>
>> >> --
>> >>
>> >>>
>> >>> /Fredrik
>> >>>
>> >>> On Sat, Mar 3, 2012 at 7:04 PM, R. Michael Weylandt <
>> >>> michael.weylandt at gmail.com> wrote:
>> >>>
>> >>>  Untested, but it might be simpler than that:
>> >>>>
>> >>>> suspicious.vowels(pb,c("Type",**"Sex","Vowel"),"F1",F2)
>> >>>>
>> >>>> Note that "F1" is in quotes but F2 isn't.
>> >>>>
>> >>>> Michael
>> >>>>
>> >>>> On Sat, Mar 3, 2012 at 5:46 PM, Fredrik Karlsson <dargosch at gmail.com>
>> >>>> wrote:
>> >>>>
>> >>>>> Dear list,
>> >>>>>
>> >>>>> Sorry, but I cannot get my head around how and I could pass
>> >>>>> arguments
>> >>>>>
>> >>>> along
>> >>>>
>> >>>>> to high-level functions. What I have is a function that would
>> >>>>> benefit
>> >>>>>
>> >>>> from
>> >>>>
>> >>>>> me using ddply from the plyr package.
>> >>>>> However, I cannot get the arguments passing part right.
>> >>>>>
>> >>>>> So, this is my function:
>> >>>>>
>> >>>>>  suspicious.vowels <-
>> >>>>>>
>> >>>>> function(data,factors,f1,f2,**evaluate.original.params=TRUE) {
>> >>>>>
>> >>>>> datOrig <- ddply(.data=data,
>> >>>>>              .variables=as.quoted(factors),
>> >>>>>              .fun=summarize,
>> >>>>>              norm=vector.space(f1,f2)[["**Vector norms"]]
>> >>>>>              )
>> >>>>>
>> >>>>>
>> >>>>> print(datOrig)
>> >>>>>
>> >>>>> }
>> >>>>>
>> >>>>> Of course, if I try to call this function, I get an error message
>> >>>>> telling
>> >>>>> me that the "f1" argument does not exist:
>> >>>>>
>> >>>>>  suspicious.vowels(pb,c("Type",**"Sex","Vowel"),"F1",F2)
>> >>>>>>
>> >>>>> Error in mean(y, na.rm = na.rm) : object 'f1' not found
>> >>>>>
>> >>>>> However, the corresponding ddply call, when called from the console,
>> >>>>> does
>> >>>>> work:
>> >>>>>
>> >>>>>
>> >>>>>>
>> >>>>>  head(ddply(pb,as.quoted(c("**Type","Sex","Vowel")),**
>> >>>> summarize,norm=vector.space(**F1,F2)[["Vector
>> >>>>
>> >>>>> norms"]]),4)
>> >>>>> Type Sex Vowel     norm
>> >>>>> 1    c   f    aa 250.1570
>> >>>>> 2    c   f    aa 497.2711
>> >>>>> 3    c   f    aa 172.3108
>> >>>>> 4    c   f    aa 109.4464
>> >>>>> ...
>> >>>>>
>> >>>>> So, how do I modify the function to pass the arguments that I supply
>> >>>>> correctly? I cannot get my head around this enough to find the
>> >>>>> correct
>> >>>>> combination of deparse /substitute /... to get this right.
>> >>>>>
>> >>>>> I would be thankful for all the help I could get on this.
>> >>>>>
>> >>>>> /Fredrik
>> >>>>>
>> >>>>> --
>> >>>>> "Life is like a trumpet - if you don't put anything into it, you
>> >>>>> don't
>> >>>>>
>> >>>> get
>> >>>>
>> >>>>> anything out of it."
>> >>>>>
>> >>>>>      [[alternative HTML version deleted]]
>> >>>>>
>> >>>>> ______________________________**________________
>> >>>>> R-help at r-project.org mailing list
>> >>>>>
>> >>>>> https://stat.ethz.ch/mailman/**listinfo/r-help<https://stat.ethz.ch/mailman/listinfo/r-help>
>> >>>>> PLEASE do read the posting guide
>> >>>>>
>> >>>>
>> >>>> http://www.R-project.org/**posting-guide.html<http://www.R-project.org/posting-guide.html>
>> >>>>
>> >>>>> and provide commented, minimal, self-contained, reproducible code.
>> >>>>>
>> >>>>
>> >>>>
>> >>>
>> >>>
>> >>> --
>> >>> "Life is like a trumpet - if you don't put anything into it, you don't
>> >>> get
>> >>> anything out of it."
>> >>>
>> >>>        [[alternative HTML version deleted]]
>> >>>
>> >>> ______________________________**________________
>> >>> R-help at r-project.org mailing list
>> >>>
>> >>> https://stat.ethz.ch/mailman/**listinfo/r-help<https://stat.ethz.ch/mailman/listinfo/r-help>
>> >>> PLEASE do read the posting guide http://www.R-project.org/**
>> >>> posting-guide.html <http://www.R-project.org/posting-guide.html>
>> >>> and provide commented, minimal, self-contained, reproducible code.
>> >>>
>> >>
>> >> David Winsemius, MD
>> >> West Hartford, CT
>> >>
>> >>
>> >
>> >
>> > --
>> > "Life is like a trumpet - if you don't put anything into it, you don't
>> > get
>> > anything out of it."
>> >
>> > ______________________________________________
>> > R-help at r-project.org mailing list
>> > https://stat.ethz.ch/mailman/listinfo/r-help
>> > PLEASE do read the posting guide
>> > http://www.R-project.org/posting-guide.html
>> > and provide commented, minimal, self-contained, reproducible code.
>> >
>>
>>
>>
>> --
>> Joshua Wiley
>> Ph.D. Student, Health Psychology
>> Programmer Analyst II, Statistical Consulting Group
>> University of California, Los Angeles
>> https://joshuawiley.com/
>
>
>
>
> --
> "Life is like a trumpet - if you don't put anything into it, you don't get
> anything out of it."



-- 
Joshua Wiley
Ph.D. Student, Health Psychology
Programmer Analyst II, Statistical Consulting Group
University of California, Los Angeles
https://joshuawiley.com/



More information about the R-help mailing list