r - 在自定义函数中使用 mutate 以突变条件作为参数

标签 r dataframe dplyr

是否可以构造一个函数,例如 my_mut(df, condition)这样df是一个数据框,condition是一个描述突变的字符串,在函数中的某个位置,df 的突变根据condition使用过吗?

例如,如果 df有一个foo列,然后运行 ​​my_mut(df, "foo = 2*foo") ,然后在 my_mut() 内的某处将会有一行生成与 df %>% mutate(foo = 2*foo) 相同的数据帧。 .

我设法用 filter 做了类似的事情使用evalparse .

update_filt <- function(df,
                        filt,
                        col){

  sub <- df %>%
    filter(eval(parse(text = filt))) %>%
    mutate("{{col}}" := 2*{{ col }})

  remain <- df %>%
    filter(eval(parse(
                text = paste0("!(",filt,")")
                ))
           )

  return(rbind(sub, remain))
}

我不确定update_filt函数是防错的,但至少在某些情况下有效,例如 library(gapminder) date_filt(gapminder, "year == 1952", pop)返回预期结果。

同样的技巧似乎不适用于 mutate尽管。例如,

update_mut <- function(df, mutation){
  # Evaluate mutation expression
  df %>% mutate(eval(parse(text = mutation))
}

产生如下结果

library(gapminder)
update_mut(gapminder, "year = 2*year")
# A tibble: 1,704 × 7
   country     continent  year lifeExp      pop gdpPercap `eval(parse(text = mutation))`
   <fct>       <fct>     <int>   <dbl>    <int>     <dbl>                          <dbl>
 1 Afghanistan Asia       1952    28.8  8425333      779.                           3904
 2 Afghanistan Asia       1957    30.3  9240934      821.                           3914
 3 Afghanistan Asia       1962    32.0 10267083      853.                           3924
 4 Afghanistan Asia       1967    34.0 11537966      836.                           3934
 5 Afghanistan Asia       1972    36.1 13079460      740.                           3944
 6 Afghanistan Asia       1977    38.4 14880372      786.                           3954
 7 Afghanistan Asia       1982    39.9 12881816      978.                           3964
 8 Afghanistan Asia       1987    40.8 13867957      852.                           3974
 9 Afghanistan Asia       1992    41.7 16317921      649.                           3984
10 Afghanistan Asia       1997    41.8 22227415      635.                           3994
# … with 1,694 more rows

不是预期的

gapminder %>% mutate(year = 2*year)

# A tibble: 1,704 × 6
   country     continent  year lifeExp      pop gdpPercap
   <fct>       <fct>     <dbl>   <dbl>    <int>     <dbl>
 1 Afghanistan Asia       3904    28.8  8425333      779.
 2 Afghanistan Asia       3914    30.3  9240934      821.
 3 Afghanistan Asia       3924    32.0 10267083      853.
 4 Afghanistan Asia       3934    34.0 11537966      836.
 5 Afghanistan Asia       3944    36.1 13079460      740.
 6 Afghanistan Asia       3954    38.4 14880372      786.
 7 Afghanistan Asia       3964    39.9 12881816      978.
 8 Afghanistan Asia       3974    40.8 13867957      852.
 9 Afghanistan Asia       3984    41.7 16317921      649.
10 Afghanistan Asia       3994    41.8 22227415      635.
# … with 1,694 more rows

最佳答案

library(dplyr, warn.conflicts = FALSE)
my_mut <- function(df, df_filter, ...){
  df %>% 
    filter({{ df_filter }}) %>% 
    mutate(newvar = 'other function stuff',
           ...)
}

example_df <- data.frame(a = c('zebra', 'some value'),
                         b = 1:2)

example_df %>% 
  my_mut(df_filter = a == 'some value', 
         b = b*5)
#>            a  b               newvar
#> 1 some value 10 other function stuff

reprex package 于 2021 年 11 月 11 日创建(v2.0.1)

如果您无法使用 ... 因为您已在函数中将其用于其他用途,则可以将 mutation 参数包装在 中tibble 调用函数时。

library(dplyr, warn.conflicts = FALSE)
my_mut <- function(df, df_filter, mutation){
  df %>% 
    filter({{ df_filter }}) %>% 
    mutate(newvar = 'other function stuff',
           {{ mutation }})
}

example_df <- data.frame(a = c('zebra', 'some value'),
                         b = 1:2)

example_df %>% 
  my_mut(df_filter = a == 'some value', 
         mutation = tibble(b = b*5))
#>            a  b               newvar
#> 1 some value 10 other function stuff

reprex package 于 2021 年 11 月 11 日创建(v2.0.1)

关于r - 在自定义函数中使用 mutate 以突变条件作为参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69922602/

相关文章:

r - Dplyr 与 group_by 变异给我不正确的值(BUG?)

python - 如何用模式(正则表达式)替换部分字符串在数据框中抛出行

python - Pandas Dataframe - 过滤数据以获得唯一的最大和最小行

r - left_join 基于 R 中最近的 LAT_LON

r - 根据 ID 将值复制到其他 NA 单元

r - 从不平衡的 html 表中提取文本和链接

r - 从 RStudio : 在 RPub 中发布时出错

python - 如何仅使用返回多个值的函数的一个特定输出来操作列条目?

r - dplyr 创建因子水平的聚合百分比

r - 修改一行数据以获得漂亮的输出(摘要), reshape - 将行拆分为新的多列