【问题标题】:Creating a function with mutate from dplyr从 dplyr 创建一个带有 mutate 的函数
【发布时间】:2019-05-04 08:30:59
【问题描述】:
test <- data.frame('prod_id'= c("shoe", "shoe", "shoe", "shoe", "shoe", "shoe", "boat", "boat","boat","boat","boat","boat"), 
               'seller_id'= c("a", "b", "c", "d", "e", "f", "a","g", "h", "r", "q", "b"), 
               'Dich'= c(1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0),
               'price' = c(120, 20, 10, 4, 3, 4, 30, 43, 56, 88, 75, 44)
                )
test

       prod_id seller_id Dich price
 1     shoe         a    1   120
 2     shoe         b    0    20
 3     shoe         c    0    10
 4     shoe         d    0     4
 5     shoe         e    0     3
 6     shoe         f    0     4
 7     boat         a    0    30
 8     boat         g    0    43
 9     boat         h    1    56
10     boat         r    0    88
11     boat         q    0    75
12     boat         b    0    44

我想创建一个新列,根据 Dich 的值获取价格列中观察值之间的差异,其中每个观察值与每个 prod_id 组中 Dich==1 的观察值取其差异。执行此操作的语法如下。

test %>% 
group_by(prod_id) %>% 
mutate(diff_p = if(any(Dich ==1)) price - price[Dich == 1] else NA)

       prod_id seller_id Dich price diff_p
 1     shoe         a    1   120      0
 2     shoe         b    0    20     -100
 3     shoe         c    0    10     -110
 4     shoe         d    0     4     -116
 5     shoe         e    0     3     -117
 6     shoe         f    0     4     -116
 7     boat         a    0    30     -26
 8     boat         g    0    43     -13
 9     boat         h    1    56       0
10     boat         r    0    88      32
11     boat         q    0    75      19
12     boat         b    0    44     -12

现在我想创建一个使用相同语法的函数,我可以在新数据帧上使用该函数并获得相同的结果。但是,当我尝试新创建的列时,只有 NA 值。我在想在函数中使用 mutate 是什么?

trans <- function(e) {e %>%
         group_by(prod_id) %>% 
         mutate(diff_p = if(any(Dich ==1)) price -price[Dich == 1] else NA)
         }

【问题讨论】:

  • trans(test) 为我工作。在新的会话中再试一次。
  • @G.Grothendieck 感谢您的回复,如果您也想发表评论,请参阅下面我对 Akrun 的回复。谢谢!

标签: r dplyr


【解决方案1】:

一种选择是使用 quosure 和评估 (!!)

library(tidyverse)
trans <- function(dat, groupCol, valCol1, valCol2) {
  groupCol <- enquo(groupCol)
  valCol1 <- enquo(valCol1)
  valCol2 <- enquo(valCol2)
  dat %>%
     group_by(!! groupCol) %>% 
     mutate(diff_p = if(any((!! valCol1) ==1)) (!!valCol2) - 
                 (!!valCol2)[(!!valCol1) == 1] else NA)
     }
trans(test, prod_id, Dich, price)
# A tibble: 12 x 5
# Groups:   prod_id [2]
#   prod_id seller_id  Dich price diff_p
#   <fct>   <fct>     <dbl> <dbl>  <dbl>
# 1 shoe    a             1   120      0
# 2 shoe    b             0    20   -100
# 4 shoe    d             0     4   -116
# 5 shoe    e             0     3   -117
# 6 shoe    f             0     4   -116
# 7 boat    a             0    30    -26
# 8 boat    g             0    43    -13
# 9 boat    h             1    56      0
#10 boat    r             0    88     32
#11 boat    q             0    75     19
#12 boat    b             0    44    -12

注意:将列名作为参数传递以将函数应用于其他数据集可能更通用

【讨论】:

  • 嘿@akrun,感谢您的回复。我正在尝试将它与 sparklyr::spark_apply() 一起使用。 spark.rstudio.com/guides/distributed-r 我不认为我可以使用多个参数,并且我有一组列列表,我将使用该函数,所以我不需要它是可概括的,尽管我确实喜欢这个解决方案。在上面链接的 spark_apply() 示例中,他们使用匿名函数 trees_tbl %>% spark_apply(function(e) lapply(e, jitter)) 如果您不介意展示我如何做到这一点或只是为具体的变量会很棒。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-29
  • 1970-01-01
  • 1970-01-01
  • 2021-02-04
相关资源
最近更新 更多