bluefoxr / COINr

COINr
https://bluefoxr.github.io/COINr/
Other
22 stars 7 forks source link

Output issue on get_opt_weights #41

Closed kelsey209 closed 9 months ago

kelsey209 commented 1 year ago

Hi @bluefoxr ! Fantastic package. Just wanted to report an issue that I found (and also a workaround).

Issue get_opt_weights can produce this error (after it has successfully completed its optimisation): Error in data.frame(Desired = desired, Obtained = crs_out, OptWeight = wopt) : arguments imply differing number of rows: 4, 3

It's caused by this line in the function:

# number of weights at specified level
  n_w <- sum(coin$Meta$Weights$Original == Level) 

And if the user has a coin where they've included weights that are equal to the input level. Eg, I put my Level 4 weight (no parent) as 1, just like in the ASEM example data set. If you try to optimise the weights at Level 1 then this error is produced. A workaround is to change the input weights to a non-integer, so it will not overlap with the Level inputs.

To reproduce

asem_coin <- new_coin(iData = ASEM_iData,
                      iMeta = ASEM_iMeta)

asem_coin <- Aggregate(asem_coin,
                       dset = "Raw",
                       w = "Original")

get_opt_weights(asem_coin,
                itarg = "equal",
                dset = "Aggregated",
                Level = 1,
                out2 = "list")
bluefoxr commented 1 year ago

Hi @kelsey209 thanks for flagging this. There was just a small bug which is now fixed, see https://github.com/bluefoxr/COINr/commit/637914bbdc5e04138eecb52be61063cf7bcec9a9

However I notice that trying to optimise weights doesn't work very well at the indicator level and often doesn't give a good solution. I think that when we are trying to optimise more weights at the same time, things get more complicated, probably the objective function response surface is not well-behaved. It might be possible to improve this somehow by respecifying the objective function, but unfortunately I don't have time to look into this at the moment.

In case you have any suggestions, the objective function is found here:

https://github.com/bluefoxr/COINr/blob/e32302441726ddb8ef40f6175c09ed105fa2e710/R/weights.R#L198

This is the sum of the squared difference between the actual correlations, and the desired correlations. Logged to avoid very small numbers. There may well be a better way to specify the problem of getting as close as possible to the target correlations.

Another possibility could be to play with the tolerance and iterations. Hope you find something that works!