2017-05-30 111 views
0

我发现自己一直在编写这一段代码,以便为分组均值生成标准差(然后用于绘制置信区间)。用于计算平均值,n,sd和标准差的Dplyr函数

虽然,在一行代码中编写我自己的函数来完成此操作将会很好。我已阅读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)) 
+0

你可以显示你所尝试过的吗?你卡在哪里?看看[nse]标签中的一些问题。 – Axeman

+0

嗯,我在博客文章中玩这个代码: 'code'mean_mpg = function(data,...,x){%>%group_by _(。dots = lazyeval :: lazy_dots(..) ))%>%综述(mean_mpg =〜均值(X)) } mtcars%>%mean_mpg(缸,齿轮,MPG) 'code' 它返回的错误不是矢量 – spindoctor

回答

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 
+0

你或许应该注意到,这只适用于'dplyr'的开发版本,而不是当前最可能使用的CRAN版本。 – Axeman

+0

我终于回到了这个;我忘记了我曾问过这个问题。 但是有可能*不包括函数中的分类分组变量?有时我会一个一个地分组,有时候会有两个分组变量。我想在自定义功能之外保持这种灵活性。但我不知道这是否可能。 – spindoctor

+0

我已经添加了一个编辑功能,可以让您以两种不同的方式进行编辑 – tbradley

相关问题