逻辑回归选择R中的正确变量

时间:2020-09-11 18:57:23

标签: r logistic-regression dummy-variable

好的,所以我有这样的数据,但是有更多类似类型的变量

Company         Job  Month  Reported  Injury.Loc  Age
      1  Cartpenter      2         0         Leg   23
      2    Mechanic     12         1         Arm   33
      3       Legal      1         1         Arm   24
      4   Carpenter      1         1         Leg   75
      5       Legal      4         0        Head   23
      3      Dental      6         1       Wrist   40

我无法对变量的分类性质进行以下逻辑回归

log_m1 <- glm(Reported ~. , data = df, family = "binomial")

有没有办法一次分解所有类别变量并保留/保留所有数字变量?

因此,基本上,可以使用代码来保留日志记录正常工作所需的变量。

错误:

Error in `contrasts<-`(`*tmp*`, value = contr.funs[1 + isOF[nn]]) : 
  contrasts can be applied only to factors with 2 or more levels

2 个答案:

答案 0 :(得分:1)

可以对数字和类别自变量混合运行逻辑回归-这就是为什么您收到错误消息的原因。

让我们首先展示我们可以无问题地进行这样的回归:

set.seed(69)

df <- data.frame(sex = factor(sample(c("Male", "Female"), 100, TRUE)),
                 age = sample(21:90, 100, TRUE),
                 outcome = sample(0:1, 100, TRUE))

glm(outcome ~ ., data = df, family = "binomial")
#> 
#> Call:  glm(formula = outcome ~ ., family = "binomial", data = df)
#> 
#> Coefficients:
#> (Intercept)      sexMale          age  
#>    0.169183     0.019774    -0.003115  
#> 
#> Degrees of Freedom: 99 Total (i.e. Null);  97 Residual
#> Null Deviance:       138.6 
#> Residual Deviance: 138.5     AIC: 144.5

但是如果我们将sex的所有值都设为相同,我们可以复制您的错误:

df2 <- within(df, sex <- rep("Male", 100))

glm(outcome ~ ., data = df2, family = "binomial")
#> Error in `contrasts<-`(`*tmp*`, value = contr.funs[1 + isOF[nn]]): 
#> contrasts can be applied only to factors with 2 or more levels

因此,您可能在数据中有一列只有一个因子水平(或只有一个唯一的非NA值)。删除它,您的回归将按预期运行。

答案 1 :(得分:0)

您可以对vtreatmagritt软件包以及dplyr使用下一种方法。这里的代码:

library(vtreat)
library(dplyr)
library(magrittr)
#Data
df <- structure(list(Company = c(1L, 2L, 3L, 4L, 5L, 3L), Job = c("Cartpenter", 
"Mechanic", "Legal", "Carpenter", "Legal", "Dental"), Month = c(2L, 
12L, 1L, 1L, 4L, 6L), Reported = c(0L, 1L, 1L, 1L, 0L, 1L), Injury.Loc = c("Leg", 
"Arm", "Arm", "Leg", "Head", "Wrist"), Age = c(23L, 33L, 24L, 
75L, 23L, 40L)), class = "data.frame", row.names = c(NA, -6L))

首先,我们必须隔离变量以在不同的数据帧中进行变换和分离(df将保留数字变量和df2类别变量):

#Isolate data variables of type character
vars <- c("Job","Injury.Loc")
df2 <- df[,vars]
df <- df[,-which(names(df) %in% vars)]

完成后,我们使用designTreatmentsZ()use_series来处理变量并在新的数据帧中进行分配:

#Code for dummy vars
treatplan <- designTreatmentsZ(df2, vars)
#Process
scoreFrame <- treatplan %>%
    use_series(scoreFrame) %>%
    select(varName, origName, code)

现在,我们使用newvarsfilter()中隔离已处理的变量:

#Select
newvars <- scoreFrame %>%
    filter(code %in% c("clean", "lev")) %>%
    use_series(varName)

我们将新变量提取到新的数据框中:

#Create new data
dframe.treat <- prepare(treatplan, df2, varRestriction = newvars)

最后,我们使用数字变量将其添加到数据框中:

#Bind with original df
newdf <- cbind(df,dframe.treat)

数据将如下所示(由于空间原因仅显示了一些变量):

  Company Month Reported Age Job_lev_x_Carpenter Job_lev_x_Cartpenter Job_lev_x_Dental
1       1     2        0  23                   0                    1                0
2       2    12        1  33                   0                    0                0
3       3     1        1  24                   0                    0                0
4       4     1        1  75                   1                    0                0
5       5     4        0  23                   0                    0                0
6       3     6        1  40                   0                    0                1

然后,您可以创建模型。请注意奇异点,否则模型可能会得出错误的结论。

#Model
log_m1 <- glm(Reported ~. , data = newdf, family = "binomial")