kosukeimai / MatchIt

R package MatchIt
206 stars 43 forks source link

cardinality matching with exact match #123

Open ilovemane opened 2 years ago

ilovemane commented 2 years ago

Hi, I found that if I use cardinality matching with exact matching, it often comes back without a solution, when an exact match on a variable with loads of categories (e.g. on a dataset with loads of clusters). I guess it due to that, if any of the clusters fail to comes back with a solution then the whole dataset won't return a solution. But in I think what we want is to exclude all the data in that clusters if it won't give a solution with cardinality match instead. I hope this makes sense to you. I think is due to these checks in the function below.

thanks,

Mike

cardinality_error_report <- function(out, solver) { if (solver == "glpk") { if (out$status == 1) { if (all(out$solution == 0)) { stop("The optimization problem may be infeasible. Try increasing the value of 'tols'.\nSee ?method_cardinality for additional details.", call. = FALSE) } else { warning("The optimizer failed to find an optimal solution in the time alotted. The returned solution may not be optimal.\nSee ?method_cardinality for additional details.", call. = FALSE) } } } else if (solver == "symphony") { if (names(out$status) %in% c("TM_TIME_LIMIT_EXCEEDED") && !all(out$solution == 0) && all(out$solution <= 1)) { warning("The optimizer failed to find an optimal solution in the time alotted. The returned solution may not be optimal.", call. = FALSE) } else if (names(out$status) != "TM_OPTIMAL_SOLUTION_FOUND") { stop("The optimizer failed to find an optimal solution in the time alotted. The optimization problem may be infeasible. Try increasing the value of 'tols'.\nSee ?method_cardinality for additional details.", call. = FALSE) } } else if (solver == "gurobi") { if (out$status %in% c("TIME_LIMIT", "SUBOPTIMAL") && !all(out$x == 0)) { warning("The optimizer failed to find an optimal solution in the time alotted. The returned solution may not be optimal.\nSee ?method_cardinality for additional details.", call. = FALSE) } else if (out$status %in% c("INFEASIBLE", "INF_OR_UNBD", "NUMERIC") || all(out$x == 0)) { stop("The optimization problem may be infeasible. Try increasing the value of 'tols'.\nSee ?method_cardinality for additional details.", call. = FALSE) } } }

ngreifer commented 2 years ago

This is a great suggestion; I will look into implementing it.

ilovemane commented 2 years ago

Cool thanks! The cardinality part of this package is fantastic btw, it really helps me with my thesis!