2017-08-14 2 views
1

J'ai une fonction personnalisée qui résume une variable. J'ai simplifié la fonction pour illustrer mon problème, c'est-à-dire qu'il est plus complexe que celui illustré ci-dessous. Notez que la structure générale de la fonction doit rester la même: Il faut un argument pour spécifier sur quelle dataframe (df), et un argument quelle variable doit résumer (variable_to_test).fonction lapply avec des arguments pour l'élément de données et la variable

my_fun <- function(df, variable_to_test) { 

    variable_to_test <- enquo(variable_to_test) 
    new_var_name <- paste0(quo_name(variable_to_test), "_new_name") 

    df %>% 
    summarise(
     !!new_var_name := sum(!!variable_to_test, na.rm = TRUE) 
    ) 
} 

En utilisant un exemple, je peux appliquer la fonction de chaque variable dans mon dataframe:

library(tidyverse) 
dat <- tibble(
    variable_1 = c(1:5, NA, NA, NA, NA, NA), 
    variable_2 = c(NA, NA, NA, NA, NA, 11:15) 
) 


> my_fun(dat, variable_1) 
# A tibble: 1 x 1 
    variable_1_new_name 
       <int> 
1     15 


> my_fun(dat, variable_2) 
# A tibble: 1 x 1 
    variable_2_new_name 
       <int> 
1     65 

Mais: comment puis-je appliquer la fonction liste sur toutes les colonnes du dataframe? J'ai essayé

> dat %>% 
+ lapply(., my_fun) 
Error in duplicate(quo) : argument "quo" is missing, with no default 
Called from: duplicate(quo) 

mais cela renvoie une erreur. Je me bats avec le fait que la fonction prend un argument à la fois pour le dataframe à travailler, et la variable à résumer. Notez que je voudrais garder cette structure - je trouve plus élégant de passer le nom de l'élément de données dans la fonction au lieu de simplement donner à la fonction le nom de la variable et de "coder" le cadre de données dans le corps de la fonction. Est-ce que quelqu'un a une bonne idée comment lapply() la fonction?

+1

Avez-vous besoin d'une solution 'dplyr' ou la base R répond-elle à vos besoins? Habituellement, vous résolvez ceci en donnant à la fonction une entrée statique et une entrée variable, par ex. 'lapply (dat, fonction (x) myfun (dat, x))'. Je ne connais pas 'dplyr', mais peut-être essayer' lapply (., Function (x) myfun (., X)) '? – LAP

+0

J'ai déjà une solution de base R. J'ai essayé de réécrire la fonction de façon «tidyeval», car elle améliore la lisibilité du corps de la fonction. Alors oui, j'ai besoin d'une solution 'tidyeval' :) – piptoma

Répondre

2

Oh, je pense que vous ne faites que cartographier la mauvaise chose. Pour la solution tidyverse je voudrais essayer:

map(dat, ~my_fun(dat, .)) 

Ce que cela fait est la carte sur les noms de colonnes et branchez la colonne à ..

1

Vous travaillez au mauvais niveau. Si vous mappez une fonction sur une trame de données, cette fonction doit prendre une colonne . Le problème ici est que la fonction my_fun() attend une trame de données plutôt qu'une colonne.

Vous devez trouver une autre façon de résoudre le problème. Une solution consiste à utiliser les cartographes fournies par dplyr:

dat %>% 
    summarise_all(sum, na.rm = TRUE) %>% 
    rename_all(paste0, "_new_name") 

Vous pouvez utiliser une combinaison équivalente de map() et set_names() de purrr.

dat %>% 
    map_df(sum, na.rm = TRUE) %>% 
    set_names(paste0, "_new_name")