2017-02-28 49 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