R mutate и map: передать объект, связанный с.? - PullRequest
0 голосов
/ 13 октября 2018

В типичном случае, когда я использую map:

out <- map(data_list, ~fo(arg1 =.))

, если fo() возвращает вызов функции (как в out[[1]]$call), он будет содержать arg1=., но этоможет вызвать проблемы, если вывод call будет использован позже (пример ниже).Как можно вместо этого получить что-то вроде arg1=data_list[[1]], то есть . оценивается (или передается, не знаю, как это назвать)?

Пример: запустить lm() регрессии с картой, с data=., т.е. map(data, ~lm(f, data = .)).Попробуйте затем обновить регрессии.Это не будет работать, так как update() будет искать out$call$data и найдет ., поэтому не будет знать, где искать.

library(tidyverse)

iris_nest <-  nest(as_tibble(iris), -Species)
regs <- map(iris_nest$data, ~lm(Sepal.Length ~ Sepal.Width + Petal.Length, data = .))

# update first?
update(regs[[1]], ~ . - Sepal.Width)
#> Error in is.data.frame(data): object '.' not found

## issue comes from:
regs[[1]]$call$data
#> .

Обходной путь: Обходной путь, который у меня есть, заключается в обратной связи с out$call$data, но, надеюсь, есть лучший способ сделать это заранее, с некоторыми eval / get/

# workaround:
regs[[1]]$call$data <- iris_nest$data[[1]]
update(regs[[1]], ~ . - Sepal.Width)
#> 
#> Call:
#> lm(formula = Sepal.Length ~ Petal.Length, data = structure(list(
#>     Sepal.Length = c(5.1, 4.9, 4.7, 4.6, 5, 5.4, 4.6, 5, 4.4, 
#>     3.4, 3.4, 2.9, 3.1, 3.7, 3.4, 3, 3, 4, 4.4, 3.9, 3.5, 3.8, 
#> SKIP SKIP SKIP
#>     0.4, 0.3, 0.2, 0.2, 0.2, 0.2)), .Names = c("Sepal.Length", 
#> "Sepal.Width", "Petal.Length", "Petal.Width"), row.names = c(NA, 
#> -50L), class = c("tbl_df", "tbl", "data.frame")))
#> 
#> Coefficients:
#>  (Intercept)  Petal.Length  
#>       4.2132        0.5423

1 Ответ

0 голосов
/ 14 октября 2018

Обзор

Чтобы обновить lm объекты во вложенном фрейме данных, необходимо явно ссылаться на данные, которые содержат переменные, используемые в stats::update() для повторного подбора линейногомодель.Вы можете сделать это, используя purrr::map2() для предоставления как объекта lm, так и объекта data.

Код

# load necessary package ----
library(tidyverse)

# load necessary data ----
iris_nest <-
  iris %>% 
  as.tibble() %>%
  nest(-Species) %>%
  # lm1 = perform linear regression for each Species
  # lm2 = update lm1 for each Species 
  #       by removing Sepal.Width from the regression
  # note: use of map2() required to explicitly reference
  #       the data being used in lm()
  mutate(lm1 = map(.x = data
                   , .f = ~ lm(Sepal.Length ~ Sepal.Width + Petal.Length
                               , data = .))
         , lm2 = map2(.x = lm1
                      , .y = data
                      , .f = ~ update(object = .x
                                      , formula. = ~ . - Sepal.Width
                                      , data = .y)))

# inspect results ---
iris_nest$lm1[[1]] %>% coefficients()
# (Intercept)  Sepal.Width Petal.Length 
#   2.3037382    0.6674162    0.2834193

iris_nest$lm2[[1]] %>% coefficients()
# (Intercept) Petal.Length 
#   4.2131682    0.5422926 

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