анализ составных формул: обработка NA и минимизация копий объектов

Я пытаюсь понять, как использовать объекты Formula. Допустим, я хотел сделать свою собственную функцию 2SLS и хочу разделить объекты, с которыми я работаю, на 4 основные группы: y = ответ; X = экзогенные переменные; E = эндогенные переменные; Z = инструменты.

Я хочу иметь возможность создавать эти объекты, не делая лишних копий данных без необходимости (скажем, большое количество N и большое количество инструментов сделали бы это чрезмерно затратным по использованию памяти/времени). Я также хочу принять во внимание NA по всем данным.

Давайте воспользуемся синтаксисом формулы, похожим на felm (я пытался посмотреть там код синтаксического анализа, но не смог за ним уследить).

frml = y ~ x1 + x2 + x3*x4 | (e1 | e2 ~ z1 + z2)

library(Formula)
N = 12 # be divisible by 6
data = data.frame(y=rnorm(N), x1=rnorm(N), x2=rnorm(N), x3=rnorm(N),
                  x4=factor(rep(1:2, N/2)), e1=rnorm(N), e2=rnorm(N),
                  z1=rnorm(N), z2=factor(rep(1:3, N/3)))
data[2,'y'] = data[3,'x1'] = data[4,'e1'] = data[5,'z2'] = NA

parse_frml = function(frml, data, subset=NULL) {
    frml = as.Formula(frml)
    # does not take into account NAs at all
    y = model.part(frml, data=data, subset=subset, lhs=1)
    # does not take into account NAs in other variables (y, Z, E)
    X = model.matrix(frml, data=data, subset=subset, lhs=0, rhs=1)
    Z = model.matrix(frml, data=data, subset=subset, lhs=0, rhs=2)
    #E =  # I can't figure this out at all
    return(list(y=y, X=X, E=E, Z=Z))
}

Теперь я могу сделать что-то вроде

mf = model.frame(frml, data=data, subset=subset, lhs=1, rhs=1)

который будет учитывать NA в y и X, но игнорирует E и Z. Далее, это копирует данные в mf, а затем снова копирует в y и X.

Итак, у меня есть 2 вопроса и 1 ограничение

  1. Как получить Е? (матрица для LHS 2-го уравнения)
  2. Как учесть NA из всех данных, используемых frml во всех матрицах?
  3. При минимизации количества копий данных (в идеале просто скопированных в матрицы)

В более общем смысле, что является хорошим ресурсом для понимания формул, формул, терминов и т.п.? Я не нашел, например. документация по пакету библиотек формул будет очень полезной.


person James    schedule 24.11.2015    source источник


Ответы (1)


Это не идеально, но это работает. Жаль, что почти нет информации о том, как на самом деле обрабатывать и манипулировать формулами в коде R. Мое решение зависит от Formula.tools

library(formula.tools)
parse_frml = function(frml, data, subset=NULL) {
    frml = as.Formula(frml)
    vars = all.vars(frml)
    other_vars = c(all.vars(formula(frml, lhs=1, rhs=1)),
                   rhs.vars(formula(frml, lhs=0, rhs=2)))
    e_vars = setdiff(vars, other_vars)
    valid = which(complete.cases(data[, vars]))
    if (!is.null(subset)) {
        if (class(subset) == 'logical') {
            subset = which(subset)
        }
        valid = intersect(valid, subset)
    }
    y = model.part(frml, data=data[valid,], lhs=1)
    X = model.matrix(frml, data=data[valid,], lhs=0, rhs=1)
    Z = model.matrix(frml, data=data[valid,], lhs=0, rhs=2)
    E = data.matrix(data[valid, e_vars])
    return(list(y=y, X=X, E=E, Z=Z))
}

Я подозреваю, что подстановка данных с действительными каждый раз довольно дорогая. Но в приведенном выше тесте это, кажется, работает.

person James    schedule 04.12.2015