从R中的lm之前的公式中删除Inf值

时间:2019-03-10 10:49:15

标签: r formula

假设我使用mtcars数据集设置任意公式:

data(mtcars)

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

我想在lm函数中使用该公式,但是在此之前,我想删除包含InfNaNNA的潜在行。从示例中,如果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 个答案:

答案 0 :(得分:2)

使用drop.terms。假设每个项由模型矩阵中的单个列表示(即,没有任何因子具有> 2级),我们计算模型矩阵mm并找到不良列的列号wx。然后使用drop.terms从terms对象中删除这些列,并从修订后的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

答案 1 :(得分:0)

您可以从要回归的数据中删除这些值。 hp == 0或gear == 0时会发生Inf。

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