【问题标题】:dplyr: Send all Columns to a function within a mutate following a group_bydplyr:在 group_by 之后将所有列发送到 mutate 中的函数
【发布时间】:2017-12-19 20:34:09
【问题描述】:

在 dplyr 管道中调用任意函数时,将当前组中的所有列作为 tibble 或 data.frame 发送到函数的首选方法是什么?

在下面的例子中,mean_B 是一个简单的例子,我知道在调用函数之前需要什么。 mean_B_fun 给出了错误的答案(与我想要的相比——我想要组内的意思),mean_B_fun_ugly 给出了我想要的答案,但这似乎既是一种低效(而且丑陋)的方式来获得我想要的效果想要。

我想对任意列进行操作的原因是,在实践中,我在下面的示例中从用户那里获取my_fun,并且我不知道用户需要先验操作的列.

library(dplyr)

my_fun <- function(x) mean(x$B)

my_data <-
  expand.grid(A=1:3, B=1:2) %>%
  mutate(B=A*B) %>%
  group_by(A) %>%
  mutate(mean_B=mean(B),
         mean_B_fun=my_fun(.),
         mean_B_fun_ugly=my_fun(as.data.frame(.)[.$A == unique(A),,drop=FALSE]))

【问题讨论】:

  • mutate_all 将按组将函数应用于除分组列之外的所有列。对于my_fun,参数x 应该是一个向量,函数中的操作应该是mean(x),因为mutate 将传递来自给定列的值向量。
  • tidyverse 中基本上有两种类型的函数:1) 将数据帧作为第一个参数的函数(用于管道,例如 tidyr::separate 或 dplyr::top_n)和 2)那些采用向量的(例如stringr 中的所有函数或许多base 函数,例如meanmaxsum)——这些通常用于mutate 语句中。有些可以采用 df 或矢量(如purrr::map),但行为会有所不同。您的用户函数应该是类型 2 - 它应该采用向量,而不是数据框。假设用户没有在函数内设置子集,group_by 将被接受。
  • @eipi10 用户可能需要将一个函数应用于多个列以获取其函数的输出。一般来说,写成mean(x$B)也可以写成mean(x$B) + mean(x$A),我不知道他们需要哪些列。
  • @dmi3kno,“您的用户函数应该...采用向量,而不是数据帧。”我不能对我的用户做出这种限制。在一个函数调用中,他们可能需要列A,在下一个函数调用中,他们可能需要列B,在下一个函数调用中,他们可能同时需要AB。更一般地说,我不知道用户数据集中的所有列名,它们对用户意味着什么,以及哪些是重要的。

标签: r dplyr


【解决方案1】:

这是我的答案,不知道您要计算平均值的列。

expand.grid(A=1:3, B=1:2) %>%
mutate(B=A*B) %>% nest(-A)  %>%
mutate(means = map(.$data, function(x) colMeans(x)))

  A data means
1 1 1, 2   1.5
2 2 2, 4     3
3 3 3, 6   4.5

【讨论】:

  • 此解决方案不会将整个 data.frame 传递给 colMeans;它似乎只通过列B
  • 它将传递您未分组的所有列:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-13
  • 2016-08-01
相关资源
最近更新 更多