【问题标题】:Dplyr function to compute average, n, sd and standard error用于计算平均值、n、sd 和标准误差的 Dplyr 函数
【发布时间】:2017-05-30 15:32:35
【问题描述】:

我发现自己一直在编写这段代码来产生组均值的标准错误(然后用于绘制置信区间)。

不过,如果能在一行代码中编写我自己的函数来完成这项工作,那就太好了。我已经阅读了 dplyr 中关于非标准评估的 nse 小插图和 this blog post 。我明白了有点,但我太菜鸟了,无法自己解决这个问题。任何人都可以帮忙吗?谢谢。

var1<-sample(c('red', 'green'), size=10, replace=T)
var2<-rnorm(10, mean=5, sd=1)
df<-data.frame(var1, var2)
df %>% 
group_by(var1) %>% 
summarize(avg=mean(var2), n=n(), sd=sd(var2), se=sd/sqrt(n))

【问题讨论】:

  • 你能展示你尝试过的东西吗?你在哪里卡住了?看看 [nse] 标签中的一些问题。
  • 好吧,我在博客文章中玩弄了这段代码:codemean_mpg = function(data, ..., x) { data %>% group_by_(.dots = lazyeval:: lazy_dots(...)) %>% summarise(mean_mpg = ~mean(x)) } mtcars %>% mean_mpg(cyl, gear, mpg) code 它返回错误 Not a Vector

标签: r dplyr nse


【解决方案1】:

您可以使用函数enquo 在函数调用中显式命名变量:

my_fun <- function(x, cat_var, num_var){
  cat_var <- enquo(cat_var)
  num_var <- enquo(num_var)

  x %>%
    group_by(!!cat_var) %>%
    summarize(avg = mean(!!num_var), n = n(), 
              sd = sd(!!num_var), se = sd/sqrt(n))
}

给你:

> my_fun(df, var1, var2)
# A tibble: 2 x 5
    var1      avg     n        sd        se
  <fctr>    <dbl> <int>     <dbl>     <dbl>
1  green 4.873617     7 0.7515280 0.2840509
2    red 5.337151     3 0.1383129 0.0798550

这与您的示例的输出相匹配:

> df %>% 
+   group_by(var1) %>% 
+   summarize(avg=mean(var2), n=n(), sd=sd(var2), se=sd/sqrt(n))
# A tibble: 2 x 5
    var1      avg     n        sd        se
  <fctr>    <dbl> <int>     <dbl>     <dbl>
1  green 4.873617     7 0.7515280 0.2840509
2    red 5.337151     3 0.1383129 0.0798550

编辑:

OP 已要求从函数中删除 group_by 语句,以添加 group_by 多个变量的功能。有两种方法可以处理这个 IMO。首先,您可以简单地删除group_by 语句并将分组数据框通过管道传输到函数中。该方法如下所示:

my_fun <- function(x, num_var){
  num_var <- enquo(num_var)

  x %>%
    summarize(avg = mean(!!num_var), n = n(), 
              sd = sd(!!num_var), se = sd/sqrt(n))
}

df %>%
  group_by(var1) %>%
  my_fun(var2)

解决此问题的另一种方法是使用...quos 以允许该函数为group_by 语句捕获多个参数。看起来像这样:

#first, build the new dataframe
var1<-sample(c('red', 'green'), size=10, replace=T)
var2<-rnorm(10, mean=5, sd=1)
var3 <- sample(c("A", "B"), size = 10, replace = TRUE)
df<-data.frame(var1, var2, var3)

# using the first version `my_fun`, it would look like this
df %>%
  group_by(var1, var3) %>%
  my_fun(var2)

# A tibble: 4 x 6
# Groups:   var1 [?]
    var1   var3      avg     n        sd        se
  <fctr> <fctr>    <dbl> <int>     <dbl>     <dbl>
1  green      A 5.248095     1       NaN       NaN
2  green      B 5.589881     2 0.7252621 0.5128378
3    red      A 5.364265     2 0.5748759 0.4064986
4    red      B 4.908226     5 1.1437186 0.5114865

# Now doing it with a new function `my_fun2`
my_fun2 <- function(x, num_var, ...){
  group_var <- quos(...)
  num_var <- enquo(num_var)

  x %>%
    group_by(!!!group_var) %>%
    summarize(avg = mean(!!num_var), n = n(), 
              sd = sd(!!num_var), se = sd/sqrt(n))
}

df %>%
  my_fun2(var2, var1, var3)

# A tibble: 4 x 6
# Groups:   var1 [?]
    var1   var3      avg     n        sd        se
  <fctr> <fctr>    <dbl> <int>     <dbl>     <dbl>
1  green      A 5.248095     1       NaN       NaN
2  green      B 5.589881     2 0.7252621 0.5128378
3    red      A 5.364265     2 0.5748759 0.4064986
4    red      B 4.908226     5 1.1437186 0.5114865

【讨论】:

  • 您可能应该注意到,这仅适用于 dplyr 的开发版本,不是当前的 CRAN 版本,这是 OP 最有可能使用的。
  • 我终于回到了这个;我忘了我问过这个。但是是否可以在函数中包含分类分组变量?有时我按一个分组,有时按两个分组变量。我想在自定义功能之外保持这种灵活性。但我不知道这是否可能。
  • 我添加了一个编辑,可以让您以 2 种不同的方式执行此操作
猜你喜欢
  • 2021-05-08
  • 1970-01-01
  • 2014-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-20
相关资源
最近更新 更多