2017-08-14 58 views
1

我有一个自定义函数,它汇总了一个变量。 我简化了函数来说明我的问题,即它比下面显示的更复杂。请注意,该函数的一般结构应该保持不变:它需要一个参数来指定要使用哪个数据帧(df)以及一个变量进行汇总的参数(variable_to_test)。lapply函数带有数据帧和变量的参数

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

使用一个例子,我可以申请在每个变量的函数在我的数据帧:

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 

但是:我怎么能列出适用于在数据帧中的所有列的功能?我试过

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

但是这会返回一个错误。我正在努力处理这个事实,即该函数为要处理的数据框以及要汇总的变量提供参数。请注意,我想保留这种结构 - 我发现将数据框的名称传递给函数会更优雅,而不仅仅是将函数的变量名称和数据框“硬编码”到函数体中。有没有人有一个好主意如何lapply()的功能?

+1

您是否需要'dplyr'解决方案,还是基础R适合您的需求?通常你可以通过给函数一个静态和一个可变的输入来解决这个问题,例如, 'lapply(dat,function(x)myfun(dat,x))'。我不熟悉'dplyr',但也许尝试'lapply(。,function(x)myfun(。,x))'? – LAP

+0

我已经有了一个基础R解决方案。我试图重写'tidyeval'方式的函数,因为它提高了函数体的可读性。所以是的,我需要一个'tidyeval'解决方案:) – piptoma

回答

2

哦,我觉得你只是在错误的东西映射。对于tidyverse解决方案,我会尝试:

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

这样做是什么地图上的列名,并插上列到.

1

您正在错误的级别工作。如果您将功能映射到数据框上,则此功能应采用。这里的问题是函数my_fun()需要一个数据框而不是一列。

您需要找到解决问题的其他方法。一种解决方案是使用由dplyr提供的映射器:

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

你可以同样使用的map()set_names()组合从purrr。

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