用函数创建复杂的公式

时间:2019-10-08 09:47:37

标签: r function if-statement

我正在使用以下函数创建公式,在这里我可以简单地分配变量名的向量,其中该函数确保所有内容都在正确的位置,并且排除了双变量名:

formula <- function(depvar, indepvars, instruments=NULL, othervars=NULL) {
    x <- c(indepvars, instruments, othervars)
    totvars <- unique(x)
    totvars <- x[!x %in% depvar]
    formula <- as.formula(
    paste(depvar, paste(totvars, collapse = " + "), sep = " ~ "))
    return(formula)
}
indepvars <- c("indepvarA", "indepvarB", "indepvarC")
instruments <- c("IV_A", "IV_B")
# lm
formula("depvar", indepvars)
# 1st stage - IV's for indepvarC
formula("indepvarC", indepvars, instruments)

但是,我想选择编写一个更复杂的公式(ivreg公式),即:

depvar ~ instrumentedvar + indepvars | instrumentvars + indepvars

我一直在尝试以下方法:

formula <- function(depvar, indepvars, instruments=NULL, instrumentedvar=NULL, othervars=NULL, twostage=NULL) {
    x <- c(indepvars, instruments, othervars)
    totvars <- unique(x)
    totvars <- x[!x %in% depvar]
    if (is.null(twostage)) {
    formula <- as.formula(
    paste(depvar, paste(totvars, collapse = " + "), sep = " ~ "))
    } else {
    totvarsB <- totvars[!totvars %in% instrumentedvar]
    totvarsB <- c(as.character(totvarsB), as.character(instruments))
    formula <- as.formula(
      paste(depvar, paste(paste(totvars, collapse = " + "), paste("|", paste(totvarsB, collapse = " + " )), sep = " ~ ")))
    }
    return(formula)
}
indepvars <- c("indepvarA", "indepvarB", "indepvarC")
instruments <- c("IV_A", "IV_B")
instrumentedvar <- "indepvarC"
formula("indepvarC", indepvars, instruments, twostage=1)

但是我似乎做得不好。

1 个答案:

答案 0 :(得分:1)

定义reform,它接受​​名称的向量,并输出一个字符串,并在其中加上加号。然后使用sprintf生成最终字符串,并使用as.formula进行转换:

reform <- function(x) paste(x, collapse = " + ")
makeFo <- function(lhs, rhs1, rhs2 = NULL, env = parent.frame()) {
  s <- sprintf("%s ~ %s", lhs, reform(c(rhs1, rhs2)))
  if (!missing(rhs2)) s <- sprintf("%s | %s", s, reform(rhs2))
  as.formula(s, env = env)
}

# test
makeFo("y", c("x1", "x2"))
## y ~ x1 + x2

makeFo("y", c("x1", "x2"), c("u1", "u2"))
## y ~ x1 + x2 + u1 + u2 | u1 + u2