简体   繁体   English

使用purrr :: map将多个参数应用于函数

[英]Use purrr::map to apply multiple arguments to a function

I have a data frame like this 我有这样的数据框

   df <- data.frame(tiny = rep(letters[1:3], 20), 
                  block = rnorm(60), tray = runif(60, min=0.4, max=2),
                  indent = sample(0.5:2.0, 60, replace = TRUE))

I nested this data frame 我嵌套了这个数据框

nm <- df%>%
       group_by(tiny)%>%
       nest()

then wrote these functions 然后编写了这些函数

library(dplyr)
library(purrr)
library(tidyr)

model <- function(dfr, x, y){
             lm(y~x, data = dfr)
         }

model1 <- function(dfr){
           lm(block~tray, data = dfr)
          }

I want to run this model for all tiny classes, so I did 我想为所有小班级运行这个模型,所以我做到了

 nm%>%
   mutate(
     mod = data %>% map(model1)
   )

the above code works fine but if I want to supply the variables as arguments like I have in the model1 function, I get errors. 上面的代码工作正常,但如果我想提供变量作为我在model1函数中的参数,我会得到错误。 This is what I do 这就是我的工作

 nm%>%
    mutate(mod = data %>% map(model(x=tray, y=block)))

I keep getting the error Error in mode(x = tray, y = block) : unused argument (y = block) . 我一直Error in mode(x = tray, y = block) : unused argument (y = block)得到错误Error in mode(x = tray, y = block) : unused argument (y = block)

Also I tried plotting these using ggplot2 我也尝试使用ggplot2绘制这些ggplot2

plot <- function(dfr, i){
    dfr %>%
    ggplot(., aes(x=tray, y=block))+
geom_point()+
xlab("Soil Properties")+ylab("Slope Coefficient")+
ggtitle(nm$tiny[i])

nm%>%
 mutate(put = data %>% map(plot))

the idea is that I want ggplot to put titles a , b , and c for each of the plots that will be produced. 我的想法是,我希望ggplot为每个将要生成的图表添加标题abc Any help would be greatly appreciated. 任何帮助将不胜感激。 Thanks 谢谢

use base function split to split data into list of groups. 使用基本功能split将数据拆分为组列表。

library( purrr )
library( ggplot2 )
df %>% 
  split( .$tiny) %>%
  map(~ lm( block ~ tray, data = .))

df %>% 
  split( .$tiny) %>%
  map(~ ggplot( data = ., aes( x = tray, y = block ) ) +
        geom_point( ) +
        xlab("Soil Properties") + 
        ylab("Slope Coefficient") +
        ggtitle( as.character( unique(.$tiny) ) ) )

Using Functions: 使用功能:

lm_model <- function( data ) 
{
  return( lm( block ~ tray, data = data ) )
}

plot_fun <- function( data )
{
  p <- ggplot( data = data, aes( x = tray, y = block ) ) +
    geom_point( ) +
    xlab("Soil Properties") + 
    ylab("Slope Coefficient") +
    ggtitle( as.character( unique(data$tiny) ) )

  return( p )
}

df %>% 
  split( .$tiny) %>%
  map(~ lm_model( data = . ) )

df %>% 
  split( .$tiny) %>%
  map(~ plot_fun( data = . ) )

Creating formula inside function 在函数内部创建公式

lm_model <- function( data, x, y ) 
{
  form <- reformulate( y, x )

  return( lm( formula = form, data = data ) )
}

df %>% 
  split( .$tiny) %>%
  map(~ lm_model( data = ., x = 'tray', y = 'block' ) )

Your solution would have worked if you had your function formulated like below. 如果您的功能如下所示,您的解决方案将起作用。

model <- function(dfr, x, y){
  lm( formula = eval(parse(text = paste('as.formula( ', y, ' ~ ', x, ')', sep = ''))),
      data = dfr)
}

If you want to use mutate with map , you'll need to also use tidyr for nest . 如果你想使用mutate with map ,你还需要使用tidyr进行nest You'll be using tibbles to store the output (or data frames with list-columns of data frames). 您将使用tibbles存储输出(或数据帧与数据帧的列表列)。

I used the functions from @Sathish's detailed answer (with some modifications). 我使用了@ Sathish的详细答案中的函数(进行了一些修改)。

library(purrr)
library(dplyr)
library(tidyr) 

df <- data.frame(tiny = rep(letters[1:3], 20), 
                 block = rnorm(60), tray = runif(60, min=0.4, max=2),
                 indent = sample(0.5:2.0, 60, replace = TRUE))

lm_model <- function( data ) 
{
  return( lm( block ~ tray, data = data ) )
}

# Altered function to include title parameter with purrr::map2
plot_fun <- function( data, title )
{
  p <- ggplot( data = data, aes( x = tray, y = block ) ) +
    geom_point( ) +
    xlab("Soil Properties") + 
    ylab("Slope Coefficient") +
    ggtitle( as.character( title ) )

  return( p )
}


results <- df %>% 
  group_by(tiny) %>% 
  nest() %>% 
  mutate(model = map(data, lm_model),
         plot = map2(data, tiny, plot_fun))

You end up with: 你最终得到:

> results

# A tibble: 3 × 4
    tiny              data    model     plot
  <fctr>            <list>   <list>   <list>
1      a <tibble [20 × 3]> <S3: lm> <S3: gg>
2      b <tibble [20 × 3]> <S3: lm> <S3: gg>
3      c <tibble [20 × 3]> <S3: lm> <S3: gg>

And you can access what you need using unnest or via extraction ( [ and [[ ) 你可以访问你所需要的使用unnest或通过萃取( [[[

> results$model[[1]]

Call:
lm(formula = block ~ tray, data = data)

Coefficients:
(Intercept)         tray  
    -0.3461       0.3998  

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM