[R] apply/return and reuse

Gabor Grothendieck ggrothendieck at gmail.com
Sun Jul 19 03:58:03 CEST 2009


Yes, it just makes it more readable.

On Sat, Jul 18, 2009 at 9:55 PM, Mark Knecht<markknecht at gmail.com> wrote:
> Yes, I sort of guess at that one and found the answer. I don't quite
> really get what this 'with' command is really doing. It seems that I
> could have written something like out$Final <- out$Initial+out$Offset.
> (Untested.) I guess it's primarily a way of not having to write the
> data.frame's name and a $ all the time? I like that it makes the
> equation somewhat more readable and I can imagine that maybe the first
> argument could be a list of data.frames thus allowing you to do a lot
> more stuff in a few lines of code?
>
> The responses you've given have been very helpful. I appreciate them.
>
> Thanks,
> Mark
>
> On Sat, Jul 18, 2009 at 5:46 PM, Gabor
> Grothendieck<ggrothendieck at gmail.com> wrote:
>> Regarding the Final column the last line should have been
>>
>> out$Final <- with(out, Initial + Offset)
>>
>> On Sat, Jul 18, 2009 at 8:33 PM, Mark Knecht<markknecht at gmail.com> wrote:
>>> Very interesting. Thanks. Very concise! interesting use of cumsum.
>>> I'll have to see if I can work that into my real code where I need to
>>> take a conditional cumsum. I think it will work.
>>>
>>> On my system the Final column doesn't seem quite right but that's OK.
>>> There's enough here for me to study and I like that it doesn't have a
>>> loop.
>>>
>>> Thanks!
>>>
>>>
>>>
>>> On Sat, Jul 18, 2009 at 5:10 PM, Gabor
>>> Grothendieck<ggrothendieck at gmail.com> wrote:
>>>> Here `out` is the same as the final value of `MyDF` in your code
>>>> using cumsum() instead of a loop:
>>>>
>>>> set.seed(123)
>>>> DF <- data.frame(cbind(Event= 1:10, Initial=0,
>>>>   Offset=round(100*rnorm(10), 0), Final=0 ))
>>>> out <- transform(DF, Initial = 10000 + c(0, head(cumsum(DF$Offset), -1)))
>>>> out$Final <- with(DF, Initial + Offset)
>>>>
>>>>
>>>> On Sat, Jul 18, 2009 at 6:59 PM, Mark Knecht<markknecht at gmail.com> wrote:
>>>>> Hi,
>>>>>   No, it's not about cumsum specifically. It's about building up the
>>>>> list as the events go by.
>>>>>
>>>>>   I managed to create this code but it does depend on a for loop.
>>>>> Notice how the Final value on each row becomes the Initial value on
>>>>> the next row. Basically I want to build a data.frame with 5-10 values
>>>>> from the previous line which will help me determine what I would do on
>>>>> the current line.
>>>>>
>>>>>   This morning I had nothing while this afternoon I have this code.
>>>>> I'm not sure if a real R programmer like you would approve so I'm
>>>>> looking to get better.
>>>>>
>>>>> Thanks,
>>>>> Mark
>>>>>
>>>>>
>>>>> InitialValue = 10000
>>>>> MarginReq = 4000
>>>>>
>>>>> MyDF = data.frame(cbind(Event= 1:10, Initial=0,
>>>>>                        Offset=round(100*rnorm(10), 0) ,
>>>>>                        Final=0 ))
>>>>>
>>>>> MyDF$Initial[1] = InitialValue
>>>>> MyDF
>>>>>
>>>>> CurrentDate = 0
>>>>> CurrentFinal = InitialValue
>>>>> MyNumRows = dim(MyDF)[1]
>>>>> MyNumRows
>>>>>
>>>>> for (n in 1:MyNumRows) {
>>>>>   ## Save values from previous row
>>>>>   MyDF$Initial[n] = CurrentFinal
>>>>>
>>>>>   # Add Offset to current value to get new total
>>>>>
>>>>>   MyDF$Final[n] = MyDF$Initial[n] + MyDF$Offset[n]
>>>>>
>>>>>   ## Save values for next row
>>>>>   CurrentFinal = MyDF$Final[n]
>>>>> }
>>>>>
>>>>> MyDF
>>>>>
>>>>> On Sat, Jul 18, 2009 at 3:34 PM, Gabor
>>>>> Grothendieck<ggrothendieck at gmail.com> wrote:
>>>>>> I am not entirely clear on what you want to do but
>>>>>> if you simply want a cumulative sum use cumsum:
>>>>>>
>>>>>> cumsum(rep(100, 5)) + 10000
>>>>>>
>>>>>> or to do cumsum using Reduce and + try:
>>>>>>
>>>>>> Reduce("+", rep(100, 5), init = 10000, acc = TRUE)
>>>>>>
>>>>>> On Sat, Jul 18, 2009 at 3:59 PM, Mark Knecht<markknecht at gmail.com> wrote:
>>>>>>> Hi Gabor,
>>>>>>>   Thanks for the pointer to Reduce. It looks quite interesting. I
>>>>>>> made an attempt to use it but I'm not clear how I would move the
>>>>>>> output of the Reduce execution on row 1 to become the Initial value on
>>>>>>> Row 2. In this output:
>>>>>>>
>>>>>>>> MyDF
>>>>>>>   Event Initial Offset Final
>>>>>>> 1      1   10000    -31  9969
>>>>>>> 2      2       0     10    10
>>>>>>> 3      3       0   -133  -133
>>>>>>> 4      4       0    -91   -91
>>>>>>> 5      5       0   -145  -145
>>>>>>> 6      6       0     74    74
>>>>>>> 7      7       0      4     4
>>>>>>> 8      8       0     19    19
>>>>>>> 9      9       0   -120  -120
>>>>>>> 10    10       0     47    47
>>>>>>>>
>>>>>>>
>>>>>>> It seems that the intended use of Reduce is for when I have all the
>>>>>>> values previously set up in the array and then want to execute the
>>>>>>> same commands down through the array. That is very powerful and makes
>>>>>>> sense in most cases, but in my case I have to calculate the values on
>>>>>>> a line-by-line basis where the execution of Reduce on row 1 (the 9969)
>>>>>>> must become the Initial value on row 2 before Reduce it's work on row
>>>>>>> 2.
>>>>>>>
>>>>>>> I think I'm not fully grasping your intentions here.
>>>>>>>
>>>>>>> Code follows.
>>>>>>>
>>>>>>> Thanks,
>>>>>>> Mark
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> InitialValue = 10000
>>>>>>>
>>>>>>> MyDF = data.frame(cbind(Event = 1:10, Initial = 0, Offset = 0 , Final = 0))
>>>>>>> MyDF$Offset = round(100*rnorm(10), 0)
>>>>>>> MyDF$Initial[1] = InitialCash
>>>>>>> MyDF
>>>>>>>
>>>>>>> AddPL = function(x) Reduce("+", x[2:3])
>>>>>>>
>>>>>>> MyDF$Final = AddPL(MyDF)
>>>>>>>
>>>>>>> MyDF
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On Fri, Jul 17, 2009 at 9:02 PM, Gabor
>>>>>>> Grothendieck<ggrothendieck at gmail.com> wrote:
>>>>>>>> See ?Reduce
>>>>>>>>
>>>>>>>> On Fri, Jul 17, 2009 at 11:10 PM, Mark Knecht<markknecht at gmail.com> wrote:
>>>>>>>>> Hi,
>>>>>>>>>   Is it possible to make something like the following code actually
>>>>>>>>> work? My goal in this example would be that I'd see results like
>>>>>>>>>
>>>>>>>>> 1   10000   10100
>>>>>>>>> 2   10100   10200
>>>>>>>>> 3   10200   10300
>>>>>>>>> 4   10300   10400
>>>>>>>>>
>>>>>>>>> In real usage the function would obviously do a lot more work, but the
>>>>>>>>> question I cannot answer myself yet is whether the apply can return a
>>>>>>>>> value from the work on one row and then use that value as the input to
>>>>>>>>> the function for the next row?
>>>>>>>>>
>>>>>>>>> Thanks,
>>>>>>>>> Mark
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> ReturnLast = function (.row, NextInitial=100) {
>>>>>>>>>   .row$Initial = as.numeric(NextInitial)
>>>>>>>>>   .row$Final = as.numeric(.row$Initial+100)
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> MyStart = 10000
>>>>>>>>> X = data.frame(cbind(Event = 1:10, Initial = 0, Final = 0))
>>>>>>>>>
>>>>>>>>> X
>>>>>>>>>
>>>>>>>>> MyStart  = apply(X, 1, ReturnLast( X, MyStart))
>>>>>>>>>
>>>>>>>>> X
>>>>>>>>>
>>>>>>>>> ______________________________________________
>>>>>>>>> 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.
>>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>




More information about the R-help mailing list