[R] apply/return and reuse
Mark Knecht
markknecht at gmail.com
Sun Jul 19 03:55:09 CEST 2009
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