2017-09-19 2 views
3

Ich möchte invoke_map verwenden, um eine Liste von Funktionen aufzurufen. Ich habe eine Reihe von Variablennamen, die ich als Argumente für jede der Funktionen verwenden möchte. Letztendlich werden die Variablennamen mit group_by verwendet.Verwenden Sie invoke_map, um Variablennamen als Argumente zu übergeben

Hier ist ein Beispiel:

library(dplyr) 
library(purrr) 
first_fun <- function(...){ 
    by_group = quos(...) 
    mtcars %>% 
    group_by(!!!by_group) %>% 
    count() 
} 

second_fun <- function(...){ 
    by_group = quos(...) 
    mtcars %>% 
    group_by(!!!by_group) %>% 
    summarise(avg_wt = mean(wt)) 
} 

first_fun(mpg, cyl) # works 
second_fun(mpg, cyl) # works 

both_funs <- list(first_fun, second_fun) 

both_funs %>% 
    invoke_map(mpg, cyl) # What do I do here? 

ich verschiedene Versuche versucht haben, die Variablennamen in Anführungszeichen zu setzen, enquo, verwenden vars Bezugs .data$mpg, etc, aber ich bin Messerstecherei im Dunkeln ein wenig.

+0

[Diese Frage] (https://stackoverflow.com/questions/43415475/how- to-parametrize-function-calls-in-dplyr-0-7/43416705 # 43416705) zeigt, wie man das Problem anwendet, indem man die Funktionen ändert, um Gruppierungsspalten von einem benannten Parameter anstelle von Punkten zu erhalten, was eine Teillösung ist. Ich bin immer noch an der Frage interessiert, wie man Variablennamen durch Punkte mit Hilfe von invoke übergibt, obwohl die Antwort vielleicht ist, Variablennamen nicht aus Punkten zu bekommen. –

+0

Man könnte denken, dass das Argument '.env' hier nützlich sein könnte, aber' invoke_map (first_fun, Liste (liste (mpg, cyl)), .env = as.environment (mtcars)) 'funktioniert auch nicht. – Axeman

Antwort

1

Das Problem ist nicht, dass Sie Punkte verwenden, es ist, dass Sie Namen verwenden und wenn map2_impl aufgerufen wird, werden diese Argumente ausgewertet.

die Sie interessieren und die Umgebung erkunden:

debugonce(map2) 
both_funs %>% invoke_map("mpg", "cyl") 

Diese auf der anderen Seite funktioniert:

first_fun2 <- function(...){ 
    mtcars %>% 
    {do.call(group_by_,list(.,unlist(list(...))))} %>% 
    count() 
} 

second_fun2 <- function(...){ 
    mtcars %>% 
    {do.call(group_by_,list(.,unlist(list(...))))} %>% 
    summarise(avg_wt = mean(wt)) 
} 

both_funs2 <- list(first_fun2, second_fun2) 
both_funs2 %>% invoke_map("mpg", "cyl") 

# [[1]] 
# # A tibble: 25 x 2 
# # Groups: mpg [25] 
# mpg  n 
# <dbl> <int> 
# 1 10.4  2 
# 2 13.3  1 
# 3 14.3  1 
# 4 14.7  1 
# 5 15.0  1 
# 6 15.2  2 
# 7 15.5  1 
# 8 15.8  1 
# 9 16.4  1 
# 10 17.3  1 
# # ... with 15 more rows 
# 
# [[2]] 
# # A tibble: 25 x 2 
# mpg avg_wt 
# <dbl> <dbl> 
# 1 10.4 5.3370 
# 2 13.3 3.8400 
# 3 14.3 3.5700 
# 4 14.7 5.3450 
# 5 15.0 3.5700 
# 6 15.2 3.6075 
# 7 15.5 3.5200 
# 8 15.8 3.1700 
# 9 16.4 4.0700 
# 10 17.3 3.7300 
# # ... with 15 more rows 
+0

Wenn das Problem darin besteht, dass die Namen ausgewertet werden, kann ich dann nicht eine der 'enquo'-Funktionen verwenden, um die Auswertung zu verzögern? –

+0

Aber Sie wollen nicht nur die Auswertung verzögern, Sie wollen überhaupt nicht bewerten. Die Zeile, die abstürzt, ist '.Call (map2_impl, environment()," .x "," .y "," .f "," list ")'. Soweit ich es verstehe, ruft C-Code und bewertet die Parameter eine Strings aufgezählt, sehe ich keinen Raum für Ihre benannten Parameter, dies zu passieren. –

+0

Ich sehe auch ein konzeptionelles Problem, diese benannten Variablen beziehen sich nicht auf vorhandene Objekte oder Spalten von einem aktuellen Objekt, sie sollten in diesem Beispiel wirklich Strings sein. –

Verwandte Themen