apply.monthly
uses period.apply
, and always indexes at the endpoint of each period. If you want different behavior, you need to use more general functions.
In this case, you can use the lapply(split(), ...)
idiom with a custom function:
do.call(rbind, lapply(split(ts,"months"), function(x) x[which.min(x)]))