1

I would like to apply an optimization by group on my own function:

Here a reproducable data set:

data <- data.frame(ID=c(1,1,1,2,2,3,3),C=c(1,1,1,2,2,3,4),
                   Lambda=c(0.5),s=c(1:7),   
                   sigma_S=c(0.5,0.4,0.3,0.7,0.4,0.5,0.8),
                   d=c(20,30,40,50,60,70,80), 
                   sigma_B=0.3,t=5,Rec=0.5,r=0.05)

My function is defined as follows (the function is trivial, i just want to understand the method):

  TestMSE <- function(LR)
  {
    d <- data
    D <- LR + d$s
    mse(d$C, D)   # mse is from the Metrics Package
   }

optimize(TestMSE,lower = 0.1, upper =1.5)

I tried using the ddply function:

test <-  ddply(data,"ID",summarise, optimize(TestMSE,lower = 0.1, upper =1.5))

But applying the ddply function I receive the same solution for all of my groups, although there is a difference by subgroups.

Thanks.

agstudy
  • 119,832
  • 17
  • 199
  • 261
New2R
  • 93
  • 6

1 Answers1

5

The problem, as @Joran pointed out is that your function TestMSE had no way of obtaining the split data from ddply. So, you should have an argument for the input data that provides the data for each group. Try something like this, maybe?

TestMSE <- function(LR, d) {
    D <- LR + d$s
    mse(d$C, D)
}

require(plyr)
require(Metrics)
test <-  ddply(data,"ID", function(x) {
    unlist(optimize(TestMSE, 0.7, x, lower = 0.1, upper =1.5))
})

#   ID   minimum objective
# 1  1 0.1000519  1.876781
# 2  2 0.1000519  7.010270
# 3  3 0.1000519  9.610322

aha, now I understand what you require. It can be done with merge:

merge(data, test, by="ID")

#   ID C Lambda s sigma_S  d sigma_B t Rec    r   minimum objective
# 1  1 1    0.5 1     0.5 20     0.3 5 0.5 0.05 0.1000519  1.876781
# 2  1 1    0.5 2     0.4 30     0.3 5 0.5 0.05 0.1000519  1.876781
# 3  1 1    0.5 3     0.3 40     0.3 5 0.5 0.05 0.1000519  1.876781
# 4  2 2    0.5 4     0.7 50     0.3 5 0.5 0.05 0.1000519  7.010270
# 5  2 2    0.5 5     0.4 60     0.3 5 0.5 0.05 0.1000519  7.010270
# 6  3 3    0.5 6     0.5 70     0.3 5 0.5 0.05 0.1000519  9.610322
# 7  3 4    0.5 7     0.8 80     0.3 5 0.5 0.05 0.1000519  9.610322    
Arun
  • 116,683
  • 26
  • 284
  • 387
  • Thanks, that works just great! Could you also explain me how to create an extra column with the minimum according the ID? – New2R Mar 03 '13 at 09:14
  • Maybe I don't follow what you require but I think the answer I've shown gives ID and the minimum along with the objective... – Arun Mar 03 '13 at 09:29
  • Yes, indeed. Additionally I would like to add a column in `d` with the value of the minimum of each `ID`. Since the length of `test` is shorter compared to `d`, I don't know how to add the column using the `transform`option in `ddply` – New2R Mar 03 '13 at 09:39