Удалить значения Inf из формулы перед lm в R - PullRequest
1 голос
/ 10 марта 2019

Допустим, я использовал набор данных mtcars для установки произвольной формулы:

data(mtcars)

myFormula <- as.formula("mpg ~ cyl + I(disp / hp) + I(wt^2) + I((qsec + vs) / gear)")

Я хотел бы использовать эту формулу внутри функции lm, но перед этим я хотел бы удалить потенциальные строки, содержащиеInf, NaN и NA.Из примера, если disp / hp приведет к любому Inf values, я бы хотел удалить строки, содержащие его.Я знаю, что могу сделать это, сначала сгенерировав новую переменную, удалив Inf, а затем запустив lm с формулой, но я бы хотел сделать это, используя термины формулы, поскольку это часть блестящего приложения, а формула является входной.

Моя попытка:

formulaTerms <- terms(myFormula)
formulaTerms <- gsub("I", "", labels(formulaTerms))
formulaTermsRatio <- formulaTerms[grep("/", formulaTerms)]

mtcarsDT <- setDT(mtcars)
mtcarsDT <- mtcarsDT[, formulaTermsRatio[1] := sym(formulaTermsRatio[1])]

Ответы [ 2 ]

2 голосов
/ 10 марта 2019

Используйте drop.terms. Предполагая, что каждый член представлен одним столбцом в матрице модели (то есть без факторов с> 2 уровнями), мы вычисляем матрицу модели mm и находим номера столбцов wx плохих столбцов. Затем используйте drop.terms, чтобы удалить эти столбцы из объекта терминов и извлечь формулу из пересмотренного объекта терминов.

mtcars[1, 3] <- Inf

# is.na is TRUE for NA or NaN; is.infinite is TRUE for Inf or -Inf
is.bad <- function(x) any(is.na(x) | is.infinite(x))

fo_terms <- terms(myFormula)  # myFormula is taken from question
mm <- model.matrix(myFormula, mtcars)
wx <- which(apply(mm[, -1], 2, is.bad))
fo_terms2 <- drop.terms(fo_terms, wx, keep.response = TRUE)
fo2 <- formula(fo_terms2)

myFormula
## mpg ~ cyl + I(disp/hp) + I(wt^2) + I((qsec + vs)/gear)

fo2
## mpg ~ cyl + I(wt^2) + I((qsec + vs)/gear)

Обновление

Если вы хотите удалить из формулы неверные строки, а не термины, то:

lm(myFormula, mtcars, subset = !apply(mm, 1, is.bad))

Обратите внимание, что lm автоматически удалит строки с NA и NaN (зависят от аргумента na.action), поэтому в этом случае вы можете упростить is.bad, чтобы проверять только Inf и -Inf.

Другим подходом было бы заменить Inf и -Inf на NA.

mtcars[is.infinite(mtcars)] <- NA

и затем выполните lm в обычном режиме.

0 голосов
/ 10 марта 2019

Вы можете удалить эти значения из данных, для которых вы регрессируете. Inf произойдет, когда hp == 0 или gear == 0.

data(mtcars)

df <- mtcars
myFormula <- as.formula("mpg ~ cyl + I(disp / hp) + I(wt^2) + I((qsec + vs) / gear)")

df <- df[!(df$hp==0 | df$gear==0),]
lm(myFormula,df)

> lm(myFormula,df)

Call:
lm(formula = myFormula, data = df)

Coefficients:
        (Intercept)                  cyl           I(disp/hp)              I(wt^2)  I((qsec + vs)/gear)  
            35.5847              -1.9639               1.0707              -0.3671              -0.1699  
...