The previous two posters basically covered everything, but since I'm on the
train with not too much to do, here's a more detailed response building on
what they said. The following code is "shovel-ready" and can be pasted
directly to your command line if you have your main data frame called "d"
available.

--------- BEGIN R CODE ---------

# This will install the (awesome) plyr package if you don't already have it
on your machine
# Feel free to comment it out if you know you have plyr already.
#install.packages("plyr")

require(plyr)
# This loads the plyr package which adds a bunch of variants on the "apply"
family
# We will use a variant below that's more appropriate for what you are
trying to do
# sapply() wouldn't be a problem, but this lets us have that little bit
extra control
# over the call that makes R great

# Create some sample data
# fish = rep(1:3,241*3)
# d2p = seq((50/241),50,(50/241))
# d2p = c(d2p,d2p,d2p)
# d = data.frame(fish,d2p)

# This creates a list of data frames, as you rightly identified.
split.df <- split(d,d$fish)

# Set up the function -- I gave it a whimsical name because I have no idea
what this
# is intended to do or why you want to do it. Of course, you should feel
free to adapt it to
# something more "professional". I don't know if you've seen the general
function syntax before,
# but this sets up a function with optional additional inputs; defaults are
set in the
# top of the function definition. They match the parameters of your problem,
so you
# won't need to change them later.

FunFishFunction <- function(fish, n = 241, n2 = 40, chemLevel = 5, chemName
= "d2p") {
    test <- 0; iters = 0
    while(test < chemLevel){
        i <- sample(1:(n-n2),1)
        test = sum(fish[i:(i+n2), chemName], na.rm=T)

        # Some catch code to make sure you don't wind up in an infinite loop
        # If you get to a large number of iterations, this will check to
make sure
        # it is possible to find the desired place and return it if
possible; marks both of these escape cases
        # so they can be identified if desired later.
        if (iters > 50) {
            s = cumsum(na.omit(fish[,chemName]))
            s = diff(s, lag = n2)
            if (max(s) < chemLevel) {
                return(c(Inf,max(s))) # Return an Infinity to indicate it
can't be done.
            } else {return(c(which.max(s>chemLevel), chemLevel))}
            # Return the first passing spot and the critical value
        }
            iters = iters + 1
    }
    return(c(i,test))
    # As noted, it's good form to explicitly return any results in a
user-defined function
    # By doing so here, we could halt function execution as noted in our
escape code above
    # We simply bind them together with c() here so both can be directly
returned
}

# This is where the plyr package comes in. It takes in a "l" -- list, "ply"s
it and returns
# a "d" -- data frame. The general plyr package has variants like llply or
aaply or
# daply or whatever you may need.  (a = array)
# It also provides a nifty progress bar for longer calculations so you don't
drive yourself crazy waiting :-)
# If you want to override the defaults we set above, simply put "n = 250" or
whatever between the
# function name and the call to the progress bar.

# The general syntax is tTply(IN,FUNC,FUNC_OPTIONS,PLY_OPTIONS)
# t is a code indicating the type of thing going in
# T indicates the type of thing coming out
# IN is the thing going in
# FUNC is the function to be "ply"d
# FUNC_OPTIONS are additional things to be passed to FUNC. There are none
here
# PLY_OPTIONS are additional options for the **ply function -- here we
invoke a progress bar.

FishConclusions = ldply(split.df,FunFishFunction, .progress = 'text')

colnames(FishConclusions) <- c("Fish Number", "i","test")
# Add informative column names to our data frame

print(FishConclusions)

------------ END R CODE --------------

Hopefully this helps!
Good luck and feel free to get in touch if I can clarify any of this or be
of further help.

Michael Weylandt

On Thu, Aug 11, 2011 at 8:02 PM, Dennis Murphy <djmu...@gmail.com> wrote:

> Hi:
>
> samp_func() doesn't return anything. Either (1) type test as the last
> line of the function body or (2) don't assign the last sum to an
> object.
>
> HTH,
> Dennis
>
> On Thu, Aug 11, 2011 at 1:59 PM, Sean Bignami <bignam...@gmail.com> wrote:
> > Hello R-universe...
> >
> > I am having trouble writing a function which contains a loop so I can
> sapply() it to a list of data frames
> >
> > Each data frame has 241 observations of 15 variables. My loop takes a
> random sample of one row until the 40 consecutive rows after the sample have
> a d2p(variable) sum greater than 5.
> >
> > here is my loop code (it works fine when applied to a 241 observation
> data frame):
> >
> >        n<-241
> >        test<-0
> >        while(test<5){
> >                i<-sample(1:n-40,1)
> >                x<-my.data.frame[seq(from=i, to=i+40),]
> >                test<-sumx[,"d2p"],na.rm=TRUE)
> >                }; i ; test
> >
> > I need this loop to be applied to EACH DATA FRAME in a list of 360 data
> frames created by splitting my master data frame, d, by each fish number.
> (contains observations for 360 fish, each with 241 observations of 15
> variables).
> >
> >        split.df<-split(d,d$fish)
> >
> > I'm kind of new at writing functions, so I'm sure this probably doesn't
> make much sense, but here is what I tried for the function:
> >
> >        samp.func<-function(f) {
> >        n<-241
> >        test<-0
> >        while(test<5){
> >                i<-sample(1:n-40,1)
> >                x<-f[seq(from=i, to=i+40),]
> >                test<-sum(x[,"d2p"],na.rm=TRUE)
> >                }}
> >
> > and then tried to apply it to my list of data frames (NOT WORKING):
> >
> >        sapply(split.df,samp.func)
> >
> > I'm pretty sure I'm missing some way to instruct that I want the loop to
> cycle through for each item (data frame) in my split.df list. I've tried to
> play around with including "for" loops with no avail...
> >
> > any ideas?
> >
> >
> >
> > here is code for a simplified mock single-fish data frame (i.e. one item
> in my split.df list) to plug into the loop if you want to try it.
> >
> > fish<-rep(1,241)
> > d2p<-seq((50/241),50,(50/241))
> > my.data.frame<-data.frame(fish,d2p)
> >
> > thanks!!
> > Sean
> >
> >
> >        [[alternative HTML version deleted]]
> >
> > ______________________________________________
> > R-help@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.
> >
>
> ______________________________________________
> R-help@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.
>

        [[alternative HTML version deleted]]

______________________________________________
R-help@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.

Reply via email to