forloop/foreach для запуска каждой переменной в данных, используя ту же модель в r

Мои данные выглядят так

q3a  q3b q3c q3d q3e ... q10d grp
1    2   3   4   5  ...  1    1
2    1   2   3   4       2    1
3    2   1   5   2  ...  1    2
2    1   2   1   1  ...  2    2 
2    3   4   1   2  ...  3    3

Я хочу провести односторонний тест по анове и дункану для каждого вопроса. Для q3a код будет

library("DescTools")
q3a <- aov(q3a ~ grp,data = pgy)
PostHocTest(q3a,method = "duncan")

Как я могу написать foreach цикл, чтобы повторить те же модели для каждой переменной в моих данных?

## List of variables:
> dput(names(duncan))
c("q3a", "q3b", "q3c", "q3d", "q3e", "q4a", "q4b", "q4d", "q4e", 
"q4f", "q4g", "q4h", "q4i", "q4j", "q4k", "q4l", "q4m", "q5b", 
"q5c", "q5d", "q6b", "q6c", "q6f", "q7b", "q7d", "q7f", "q7g", 
"q7h", "q7i", "q8a", "q8b", "q9a", "q9b", "q9c", "q9d", "q10a", 
"q10b", "q10c", "q10d")

Спасибо!

2 ответа

Это не метод, использующий foreach скорее это метод, использующий dplyr пакет и purrr пакет. Этот метод позволит вам расширить то, что уже сделано для дальнейшего анализа.

# first load the packages
library(dplyr)
library(purrr)

# read in data
pgy <- read.table(text = "
1    2   3   4   5  1    1
2    1   2   3   4  2    1
3    2   1   5   2  1    2
2    1   2   1   1  2    2 
2    3   4   1   2  3    3", 
                  col.names = c("q3a", "q3b", "q3c", 
                                "q3d", "q3e", "q10d", "grp"))

# data manipulation to get dataframe in required format
results <- pgy %>% 

# use this mutate call to convert grp to factor
# you may not need to do this if that column is already a factor
mutate(grp = factor(grp)) %>% 

# this gather function will convert the table from wide to long
# this is necessary to do the group_by() %>% nest() combo
# the q3a:q10d should work for you if that is the range of questions
# if not then you can change it to the first and last column names
# containing question data - these should be unquoted
gather(key = "question", value = "result", q3a:q10d) %>% 

# this creates groupings based on which question
group_by(question) %>% 

# this creates nested dataframes for each group - known as list-columns
# the column name of the nested dataframes will be data unless 
# explicitly specified
nest() %>% 

# this is where it gets a little tricky
# you can use a mutate call to create a new column, but since your
# data for each column is now stored in a nested list, you need to use
# map from the purrr package to operate on it.
# the ~ symbol is a short cut to allow you to avoid writing an anonymous function
# the .x in the aov function represents the data object in the map call
# notice that data is also the name of the listed column 
mutate(aov_test = map(data, ~ aov(result ~ grp, data = .x)),

       # this is the real magic of this method, you can use the variable created 
       # in the first line on the mutate function as the input to the 
       # second line for your PostHocTest input
       duncan = map(aov_test, ~DescTools::PostHocTest(x = .x, method = "duncan"))) 

Затем вы можете получить доступ к результатам теста Дункана следующим образом:

results$duncan[[1]]

или просмотреть их все:

map(1:nrow(results), ~ results$duncan[[.x]])

Для теста AOV вы можете использовать broom пакет, чтобы получить результаты в аккуратном фрейме данных, как это:

results %>%
  unnest(map(aov_test, broom::tidy), .drop = TRUE)

Вы можете проверить другие основные broom функции (augment() а также glance()) чтобы увидеть другую информацию о модели. К сожалению, похоже, что нет более аккуратного теста, который вы делаете.

Вот отличное решение для моей проблемы, используя lapply:

## list of names of my data 
> dput(names(duncan))
c("grp", "q3a", "q3b", "q3c", "q3d", "q3e", "q4a", "q4b", "q4d", 
"q4e", "q4f", "q4g", "q4h", "q4i", "q4j", "q4k", "q4l", "q4m", 
"q5b", "q5c", "q5d", "q6b", "q6c", "q6f", "q7b", "q7d", "q7f", 
"q7g", "q7h", "q7i", "q8a", "q8b", "q9a", "q9b", "q9c", "q9d", 
"q10a", "q10b", "q10c", "q10d")

## use lapply to run model for each variable 
results <- lapply(duncan[,-1], function(x) PostHocTest(aov(x ~ pgy, data = duncan), method = "duncan"))

## extract results for each variable
results$q3a

  Posthoc multiple comparisons of means : Duncan's new multiple range test 
    95% family-wise confidence level

$pgy
                 diff      lwr.ci     upr.ci   pval    
PGY2-PGY1  0.10716048  0.04104755 0.17327342 0.0012 ** 
PGY3-PGY1  0.05197694 -0.01485439 0.11880828 0.1274    
PGY3-PGY2 -0.05518354 -0.12593368 0.01556661 0.1263    

---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

results$q3b
etc..

Я нашел похожее решение здесь: Цикл линейной регрессии для каждой независимой переменной отдельно от зависимой

Другие вопросы по тегам