File: matchit.R

package info (click to toggle)
matchit 2.4-13-2
  • links: PTS
  • area: main
  • in suites: squeeze
  • size: 2,040 kB
  • ctags: 51
  • sloc: makefile: 24; csh: 13
file content (81 lines) | stat: -rw-r--r-- 2,540 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
matchit <- function(formula, data, method = "nearest", distance = "logit",
                    distance.options=list(), discard = "none",
                    reestimate = FALSE, ...) { 

  #Checking input format
  #data input
  mcall <- match.call()
  if(is.null(data)) stop("Dataframe must be specified",call.=FALSE)
  if(!is.data.frame(data)){
    stop("Data must be a dataframe",call.=FALSE)}
  if(sum(is.na(data))>0)
    stop("Missing values exist in the data")
  # list-wise deletion
  # allvars <- all.vars(mcall)
  # varsindata <- colnames(data)[colnames(data) %in% all.vars(mcall)]
  # data <- na.omit(subset(data, select = varsindata))
  
  ## 7/13/06: Convert character variables to factors as necessary
  ischar <- rep(0, dim(data)[2])
  for (i in 1:dim(data)[2]) 
	if(is.character(data[,i])) data[,i] <- as.factor(data[,i])
  
  ## check inputs
  if (!is.numeric(distance)) {
    fn1 <- paste("distance2", distance, sep = "")
    if (!exists(fn1))
      stop(distance, "not supported.")
  }
  fn2 <- paste("matchit2", method, sep = "")
  if (!exists(fn2))
    stop(method, "not supported.")

  ## obtain T and X
  tt <- terms(formula)
  attr(tt, "intercept") <- 0
  mf <- model.frame(tt, data)
  treat <- model.response(mf)
  X <- model.matrix(tt, data=mf)

  ## estimate the distance measure
  if (method == "exact") {
    distance <- out1 <- discarded <- NULL
    if (!is.null(distance))
      warning("distance is set to `NULL' when exact matching is used.")
  } else if (is.numeric(distance)){
    out1 <- NULL
    discarded <- discard(treat, distance, discard, X)
  } else {
    if (is.null(distance.options$formula))
      distance.options$formula <- formula
    if (is.null(distance.options$data))
      distance.options$data <- data
    out1 <- do.call(fn1, distance.options)
    discarded <- discard(treat, out1$distance, discard, X)
    if (reestimate) {
      distance.options$data <- data[!discarded,]
      distance.options$weights <- distance.options$weights[!discarded]
      tmp <- out1
      out1 <- do.call(fn1, distance.options)
      tmp$distance[!discarded] <- out1$distance
      out1$distance <- tmp$distance
    }
    distance <- out1$distance
  }

  ## matching!
  out2 <- do.call(fn2, list(treat, X, data, distance=distance, discarded, ...)) 
  
  ## putting all the results together
  out2$call <- mcall
  out2$model <- out1$model
  out2$formula <- formula
  out2$treat <- treat
  if (is.null(out2$X)){
    out2$X <- X
  }
  out2$distance <- distance
  out2$discarded <- discarded
  
  return(out2)
}