Циклы по спискам переменных - встроенные циклы

Я давний пользователь STATA, наконец, пытаюсь освоить R, чтобы улучшить свою графику. В следующем коде я подгоняю GAM к переменной результата y1, используя 5 переменных воздействия x1–x5, а затем строю прогнозы для x1.

Что я хочу сделать, так это иметь два цикла, один из которых встроен в другой, так что первый цикл повторяется по 5 результатам, подбирая GAM для каждого, а затем во встроенном втором цикле он повторяет 5 экспозиций, строя прогнозы. для каждого. В результате получится двадцать пять графиков по 5 переменных для каждого из пяти GAM. В реальной базе данных переменные не пронумерованы, поэтому она должна перебирать имена переменных как строки.

y1.gam <- mgcv::gam(y1~s(x1,bs="cr",fx=TRUE)+
                   s(x2,bs="cr",fx=TRUE)+
                   s(x3,bs="cr",fx=TRUE)+
                   s(x4,bs="cr",fx=TRUE)+
                   s(x5,bs="cr",fx=TRUE)+
                  family = poisson(link = "log"),
                  data = data)
y1.x1.plot <- plotGAM(gamFit = y1.gam , smooth.cov = "x1", groupCovs = NULL,
       plotCI=TRUE, orderedAsFactor = FALSE)

Если это поможет, вот как это будет выглядеть в STATA:

global outcome y1 y2 y3 y4 y5
global exposure x1 x2 x3 x4 x5

foreach v of varlist $outcome {
    gam `v’ $exposure, …
    foreach w of varlist $exposure{
         plot `w’…
    }
}

Надеюсь, вы можете помочь.

Спасибо.

Джош


person Josh Colston    schedule 27.03.2020    source источник
comment
Пожалуйста, не могли бы вы включить некоторые тестовые данные (используйте dput(my_data)), это облегчит людям помощь. Также был бы полезен рисунок, показывающий желаемый сюжет.   -  person Richard Telford    schedule 28.03.2020


Ответы (1)


Попробуй это. Использовался mtcars в качестве примера набора данных, даже если он точно не является подходящим примером набора данных для такого типа модели. Однако я надеюсь, что этого достаточно, чтобы показать общий подход. Ключом к циклам является использование substitute для настройки объекта формулы для шага оценки. Результатом является список, содержащий модели, графики, формулы, ...

vars_outcome <- c("mpg", "disp")
vars_exposure <- c("hp", "qsec")

# Grid of outcome and exposure variables
vars_grid <- expand.grid(out = vars_outcome, exp = vars_exposure, stringsAsFactors = FALSE)
# Init list for formulas, models, plots
mods <- list(out = vars_grid$out, exp = vars_grid$exp, fmla = list(), mod = list(), mod = list())

for (i in seq_len(nrow(vars_grid))) {
  # Set up the formula
  mods$fmla[[i]] <- substitute(out ~ s(exp, bs="cr",fx=TRUE), list(out = as.name(mods$out[[i]]), exp = as.name(mods$exp[[i]])))
  # Estimate Model
  mods$mod[[i]] <- mgcv::gam(mods$fmla[[i]], family = poisson(link = "log"), data = mtcars)
  # Plot Model
  mods$plt[[i]] <- voxel::plotGAM(gamFit = mods$mod[[i]] , smooth.cov = mods$exp[[i]], groupCovs = NULL, plotCI=TRUE, orderedAsFactor = FALSE)

  # Create a "variable" containing the plot 
  assign(paste(mods$out[[i]], mods$exp[[i]], sep = "_"), mods$plt[[i]])

}

## Name the list with the plots
names(mods$plt) <- paste(mods$out, mods$exp, sep = "_")

mods$fmla[[1]]
#> mpg ~ s(hp, bs = "cr", fx = TRUE)
mods$mod[[1]]
#> 
#> Family: poisson 
#> Link function: log 
#> 
#> Formula:
#> mpg ~ s(hp, bs = "cr", fx = TRUE)
#> attr(,".Environment")
#> <environment: R_GlobalEnv>
#> 
#> Estimated degrees of freedom:
#> 9  total = 10 
#> 
#> UBRE score: -0.1518201
mods$plt[[1]]

Создано 28 марта 2020 г. с помощью пакета reprex (v0.3.0)

person stefan    schedule 28.03.2020
comment
Спасибо. Это работает как шарм. Есть только одна маленькая проблема. Названия участков - это просто цифры. Как я могу назвать их в соответствии с комбинацией переменных результата/воздействия? (Я знаю, что это кажется тривиальным, но на самом деле я работаю с гораздо более длинным списком переменных, чем в примере). - person Josh Colston; 28.03.2020
comment
Не за что. Установка имен — простая задача. Вы можете установить имена графиков, например. вот так: names(mods$plt) <- paste(mods$out, mods$exp, sep = "_"). - person stefan; 28.03.2020
comment
Спасибо. Но где я могу поместить команду имен в скрипт и должен ли я использовать [[i]] (то есть имена (mods$plt[[i]])). Когда я запускаю команду, я получаю ошибку в именах (mods $ plt [[i]]) ‹- paste (mods $ out, mods $ exp, sep = _): атрибут «names» [40] должен быть той же длины, что и вектор [1] - person Josh Colston; 29.03.2020
comment
Привет Джош. Извиняюсь. Просто поместите команду после цикла. Я только что отредактировал свой код соответствующим образом. - person stefan; 29.03.2020
comment
Спасибо. Я не думаю, что это сработало. Должна быть куча графиков с именами y1_x1, y1_x2 и т. Д. Но они, похоже, не называются так, и я все еще могу вызывать графики, только набрав, например. моды$plt[[9]]. Извините, если я упустил что-то очевидное. - person Josh Colston; 30.03.2020
comment
Хм. Только что проверил код. После установки имен должна быть возможность вызывать график по имени, например: mods$plt$mpg_hp или mods$plt[["mpg_hp"]]. Однако я добавил строку кода в цикл for. Используя функцию assign, она создает переменную для каждого графика на лету, так что график можно вызвать, набрав mpg_hp. - person stefan; 30.03.2020
comment
Не за что. Если хотите, сделайте мне одолжение: отметьте вопрос как отвеченный. Помимо того, что я отдаю должное, это показывает другим с похожей проблемой, что решение сработало, и удаляет вопрос из очереди вопросов, все еще ожидающих ответа. - person stefan; 30.03.2020