R mutate和map:传递链接到。?的对象。

时间:2018-10-12 23:06:30

标签: r tidyverse purrr

在典型情况下,我使用map

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

如果fo()返回对函数的调用(如out[[1]]$call),它将包含arg1=.,但是如果call的输出为稍后再使用(下面的示例)。我该如何代替arg1=data_list[[1]]之类的东西,即.被评估(或传递给(不确定如何调用))?

示例:使用lm()(即data=.)和map运行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 :(得分:1)

概述

要更新嵌套数据框中的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 #