Итерация по именам переменных с использованием цикла или функции - PullRequest
0 голосов
/ 05 июня 2018

Я хочу перебрать переменные внутри фрейма данных, используя цикл for или функцию в R. Я кодировал следующее (что не работает):

y <- c(0,0,1,1,0,1,0,1,1,1)
var1 <- c("a","a","a","b","b","b","c","c","c","c")
var2 <- c("m","m","n","n","n","n","o","o","o","m")

mydata <- data.frame(y,var1,var2)

myfunction <- function(v){
  regressionresult <- lm(y ~ v, data = mydata)
  summary(regressionresult) 
}
myfunction("var1")

Когда я пытаюсь запустить это, Я получаю сообщение об ошибке:

Error in model.frame.default(formula = y ~ v, data = mydata, drop.unused.levels = TRUE) : variable lengths differ (found for 'v')

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

regressionresult <- lm(y ~ var1, data = mydata) summary(regressionresult)

Как я могу исправить функцию или поместить имена переменных в цикл?

[Я также пытался перебрать имена переменных, но у меня возникла та же проблема, что и с функцией:

for(v in c("var1","var2")){
  regressionresult <- lm(y ~ v, data = mydata)
  summary(regressionresult)  
}

При запуске этого цикла выдается ошибка:

Error in model.frame.default(formula = y ~ v, data = mydata, drop.unused.levels = TRUE) : 
  variable lengths differ (found for 'v')

Спасибо за вашу помощь!

Ответы [ 2 ]

0 голосов
/ 05 июня 2018

Вы можете использовать функции в tidyverse для работы с аккуратными данными и применения модели к различным формулам.

y <- c(0,0,1,1,0,1,0,1,1,1)
var1 <- c("a","a","a","b","b","b","c","c","c","c")
var2 <- c("m","m","n","n","n","n","o","o","o","m")

library(tidyverse)
mydata <- data_frame(y,var1,var2)

res <- mydata %>%
  # get data in long format - tidy format
  gather("var_type", "value", -y) %>%
  # we want one model per var_type
  nest(-var_type) %>%
  # apply lm on each data
  mutate(
    regressionresult = map(data, ~lm(y ~ value, data = .x))
  )
res
#> # A tibble: 2 x 3
#>   var_type data              regressionresult
#>   <chr>    <list>            <list>          
#> 1 var1     <tibble [10 x 2]> <S3: lm>        
#> 2 var2     <tibble [10 x 2]> <S3: lm>
summary(res$regressionresult[[1]])
#> 
#> Call:
#> lm(formula = y ~ value, data = .x)
#> 
#> Residuals:
#>     Min      1Q  Median      3Q     Max 
#> -0.7500 -0.3333  0.2500  0.3125  0.6667 
#> 
#> Coefficients:
#>             Estimate Std. Error t value Pr(>|t|)
#> (Intercept)   0.3333     0.3150   1.058    0.325
#> valueb        0.3333     0.4454   0.748    0.479
#> valuec        0.4167     0.4167   1.000    0.351
#> 
#> Residual standard error: 0.5455 on 7 degrees of freedom
#> Multiple R-squared:  0.1319, Adjusted R-squared:  -0.1161 
#> F-statistic: 0.532 on 2 and 7 DF,  p-value: 0.6094

Пакет метлы может помочь вам работать с результатом, тогда

library(broom)
#> Warning: le package 'broom' a été compilé avec la version R 3.4.4
res <- res %>%
  mutate(tidy_summary = map(regressionresult, broom::tidy))
res         
#> # A tibble: 2 x 4
#>   var_type data              regressionresult tidy_summary        
#>   <chr>    <list>            <list>           <list>              
#> 1 var1     <tibble [10 x 2]> <S3: lm>         <data.frame [3 x 5]>
#> 2 var2     <tibble [10 x 2]> <S3: lm>         <data.frame [3 x 5]>

Вы можете получить один из сводных данных

res$tidy_summary[[1]]
#>          term  estimate std.error statistic   p.value
#> 1 (Intercept) 0.3333333 0.3149704 1.0583005 0.3250657
#> 2      valueb 0.3333333 0.4454354 0.7483315 0.4786436
#> 3      valuec 0.4166667 0.4166667 1.0000000 0.3506167

или отменить, чтобы получить данные.frame для работы.

res %>% 
  unnest(tidy_summary)
#> # A tibble: 6 x 6
#>   var_type term        estimate std.error statistic p.value
#>   <chr>    <chr>          <dbl>     <dbl>     <dbl>   <dbl>
#> 1 var1     (Intercept)    0.333     0.315     1.06    0.325
#> 2 var1     valueb         0.333     0.445     0.748   0.479
#> 3 var1     valuec         0.417     0.417     1.000   0.351
#> 4 var2     (Intercept)    0.333     0.315     1.06    0.325
#> 5 var2     valuen         0.417     0.417     1       0.351
#> 6 var2     valueo         0.333     0.445     0.748   0.479

Интересующие функции: nest и unnest из [tidyr] [http://tidyr.tidyverse.org/), позволяющие легко создавать столбцы списка, mapот purrr, что позволяет перебирать список и применять функцию (здесь lm) и tidy из broom пакета, который предлагает функции для отображения результатов моделей(сводные результаты, прогнозируемые результаты, ...)

Здесь не используется, но знайте, что пакет modelr помогает выполнять конвейеры при моделировании.

0 голосов
/ 05 июня 2018

Мы можем использовать paste для создания формулы, чтобы передать ее на lm

myfunction <- function(v){
  regressionresult <- lm(paste0('y ~', v), data = mydata)
  summary(regressionresult) 
}
out1 <- myfunction("var1")

Или использовать glue::glue

myfunction <- function(v){
  regressionresult <- lm(glue::glue('y ~ {v}'), data = mydata)
  summary(regressionresult) 
 }
myfunction("var1")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...