Соответствующая матрица индикаторов именам столбцов в R - PullRequest
0 голосов
/ 20 апреля 2020

вопрос, который я пытаюсь решить: «Как я могу создать автоматизированную последовательность кода, которая будет извлекать названия заголовков желаемых столбцов из набора данных, чтобы соответствовать общей линеаризованной модели (glm)?» У меня есть набор данных с 8 переменными; однако я хочу использовать только 3 из них для перекрестной проверки и нахождения «лучшей» модели. Вот что я придумала:

library(boot)
salary <- read.csv("salary_data.csv")
vars <- colnames(salary[c(2,3,7)])
nvars <- length(vars)
list.to.expand = vector(mode = "list", length = nvars)
for (i in 1:nvars){
  list.to.expand[[i]]=c(0,1)
}
model.spec.matrix <- expand.grid(list.to.expand)
vars
model.spec.matrix
names(model.spec.matrix) <- vars
vars.to.use <- model.spec.matrix[2,]
vars.to.use <- as.numeric(vars.to.use)
cn <- c()
for (i in 1:nrow(model.spec.matrix)){
  if(i==1){cn <- colnames(model.spec.matrix[sapply(model.spec.matrix[i,], function(x) x > 0)]) 
  }
}
print(cn)
paste(cn, collapse = "+")
glm.out = glm(paste("LogACG~",paste(cn,collapse = "+"),sep = ""), family = gaussian, data = salary)
cv.err = cv.glm(salary, glm.out, K = 10)$delta[1]

Моя проблема заключается в том, что l oop. Я попытался создать al oop, который будет добавлять значения из "vars" в "model.use", но я не могу заставить его читать после 2-й строки в матрице. Какие-либо предложения? Спасибо

1 Ответ

1 голос
/ 21 апреля 2020

Кажется, что здесь происходит несколько вещей.

Вы сделали LogACG пояснительной переменной в вашей второй строке ("LogACG~, но это также одна из * 1005). * которые в конечном итоге заканчиваются на model.vars из-за vars <- colnames(salary[c(2,3,7)]), так что это не правильно.

Далее ваш второй for l oop должен перебирать строки model.spec.matrix, то есть

for(i in 1:nrow(model.spec.matrix)){

и для программного захвата имен столбцов (переменных), указанных в этой строке, вы можете сделать

cn <- colnames(model.spec.matrix[sapply(model.spec.matrix[i,], function(x) x > 0)])

в пределах l oop. Вам также следует переместить glm и cv.glm внутри l oop.

Однако это будет перезаписывать glm.out и cv.err каждый раз, так что вы захотите создать их как пустые списки и добавлять список в каждой итерации.

Таким образом, конечный продукт будет выглядеть следующим образом:

# Since you can't use LogACG to explain itself, 
#    suppose you meant to use Engineering as a candidate X
vars <- colnames(salary[c(2,3,8)])

# Make your grid
model.spec.matrix        <- expand.grid(list.to.expand)
names(model.spec.matrix) <- vars

glm.out <- list(rep(NA, nrow(model.spec.matrix)))
cv.err  <- list(rep(NA, nrow(model.spec.matrix)))

for(i in 1:nrow(model.spec.matrix)){
  cn <- colnames(model.spec.matrix[sapply(model.spec.matrix[i,], function(x) x > 0)])
  if(length(cn) == 0){cn <- "."}  
  tmp        <- glm(as.formula(paste("LogACG~",paste(cn,collapse = "+"),sep = "")), family = gaussian, data = salary)
  glm.out[i] <- capture.output(tmp$formula)
}
# > glm.out
# [[1]]
# [1] "LogACG ~ ."
# 
# [[2]]
# [1] "LogACG ~ Rank_Code"
# 
# [[3]]
# [1] "LogACG ~ Gender"
# 
# [[4]]
# [1] "LogACG ~ Rank_Code + Gender"
# 
# [[5]]
# [1] "LogACG ~ Engineering"
# 
# [[6]]
# [1] "LogACG ~ Rank_Code + Engineering"
# 
# [[7]]
# [1] "LogACG ~ Gender + Engineering"
# 
# [[8]]
# [1] "LogACG ~ Rank_Code + Gender + Engineering"

Чтобы получить весь объект модели в элементе списка замените

glm.out[i] <- capture.output(tmp$formula)

на

glm.out    <- append(glm.out, tmp)

т.е.

for(i in 1:nrow(model.spec.matrix)){
  cn <- colnames(model.spec.matrix[sapply(model.spec.matrix[i,], function(x) x > 0)])
  if(length(cn) == 0){cn <- "."}  
  tmp        <- glm(as.formula(paste("LogACG~",paste(cn,collapse = "+"),sep = "")), family = gaussian, data = salary)
  tmp1       <- cv.glm(salary, tmp, K = 10)$delta[1]
  glm.out    <- append(glm.out, tmp)
  cv.err     <- append(cv.err, tmp1)
}

> tail(cv.err)
[[1]]
[1] 2.751025

[[2]]
[1] 2.758954

[[3]]
[1] 2.735063

[[4]]
[1] 2.768075

[[5]]
[1] 2.774433

[[6]]
[1] 2.748291

Кроме того, вы можете быть лучше обслужили нас пакет типа bestglm или просто функция step из pacakge по умолчанию stats (см. ?step).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...