[R] apply/return and reuse
Gabor Grothendieck
ggrothendieck at gmail.com
Sun Jul 19 02:46:52 CEST 2009
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