2017-02-28 177 views
1

我有这样使用purrr ::地图将多个论点也适用于功能

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)) 

数据帧嵌套在我这个数据帧

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

然后写这些功能

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

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

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

我想运行这个模型的所有小类,所以我做了

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

上面的代码工作正常,但如果我想提供变量作为参数,如我在model1函数中,我会得到错误。这是我做

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

我不断收到错误 Error in mode(x = tray, y = block) : unused argument (y = block)

我也尝试过使用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)) 

的想法是,我想ggplot把标题绘制这些一个bç每个将要产生的地块。 任何帮助将不胜感激。谢谢

+0

看起来并不像'MODEL1( )'被定义为采取任何参数 – Nate

+0

@PierreLafortune,它没有工作。我得到错误'错误:is.data.frame(.data)|| is.list(.data)|| is.environment(.data)不是TRUE' – Kay

+1

有一天,你的孩子将停止尝试管道的一切 –

回答

3

使用基本功能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)))) 

使用功能:

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 = .)) 

创建公式中的功能

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')) 

您的解决方案,如果你有你的功能制定了类似下面会工作。

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

这工作就像我在我的问题中给出的模型示例。我开始学习另一种做得很好的方法。不过,我希望能够使用一个函数,并在使用'map'时提供我想要的函数的任何参数。 – Kay

+0

你没有回答其中的一部分。在你的'lm_model'函数中,我可以更改'block'和'tray'并将它们作为参数提供给函数吗?我该怎么做? – Kay

+0

是的。所以在这种情况下,我会将数据框,'x'变量和'y'变量传递给'lm_model'函数并使用'map'函数进行评估 – Kay

2

如果你想使用mutatemap,你也需要使用tidyrnest。你将使用骰子来存储输出(或数据框与数据框的列表)。

我使用了@ 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)) 

你结束:

> 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> 

,您可以访问你所需要的使用unnest或通过萃取([[[

> results$model[[1]] 

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

Coefficients: 
(Intercept)   tray 
    -0.3461  0.3998 
+0

我现在可以将标题添加到我的图中。谢谢 – Kay