为什么 ``mean`` 函数在函数环境中不能与 ``group_by %>% summarise`` 一起正常工作?
Why does the ``mean`` function not work properly with ``group_by %>% summarise`` in a function environement?
例如:
df <- data.frame("Treatment" = c(rep("A", 2), rep("B", 2)), "Price" = 1:4, "Cost" = 2:5)
我想通过对所有变量的处理来汇总数据,并将它们放在一起,所以我定义了一个函数来首先对每个变量执行此操作,然后 rbind
稍后再对它们进行处理。
SummarizeFn <- function(x,y,z) {
df1 <- x %>% group_by(Treatment) %>%
summarize(n = n(), Mean = mean(y), SD = sd(y)) %>%
df1$Var = z # add a column to show which variable those statistics belong to.
}
SumPrice <- SummarizeFn(df, df$Price, "Price")
然而,结果是:
Treatment n Mean SD Var
<fct> <int> <dbl> <dbl> <chr>
1 A 2 2.5 1.29 Price
2 B 2 2.5 1.29 Price
它们是所有观察值的平均值和标准差,但不是按治疗分组的观察值。这里有什么问题?
如果我将代码从函数环境中取出,它完全可以正常工作。请帮助,谢谢。
如果你有更好的方法达到我的目的,那就太好了!谢谢!
这涉及到评价标准的问题。这很有趣,我刚刚写了一个article on the subject。这很难用 dplyr
传递字符串名称。如果您需要这样做,请使用 rlang::sym
(或 rlang::syms
)和 !!
(或 !!!
)
关于你的问题,我想data.table
给你一个简洁的解决方案
dt <- as.data.table(mtcars)
output <- dt[,lapply(.SD, function(d) return(list(.N,mean(d),sd(d)))),
.SDcols = c("mpg","qsec")]
output[,'stat' := c("observations","mean","sd")]
output
# output
# mpg qsec stat
# 1: 32 32 observations
# 2: 20.09062 17.84875 mean
# 3: 6.026948 1.786943 sd
我建议使用 lapply
的匿名函数,但您可以使用在摘要步骤之前定义的更复杂的函数。如果需要,请更改 .SDcols
以包含更多变量
当您在 dplyr
管道中将变量与 $
一起使用时,它们不遵循分组,并且就像它们应用于整个数据帧一样工作。除此之外,您可以使用 {{}}
来计算函数中的列名。
library(dplyr)
SummarizeFn <- function(x,y,z) {
x %>%
group_by(Treatment) %>%
summarize(n = n(), Mean = mean({{y}}), SD = sd({{y}}), Var = z)
}
SummarizeFn(df, Price, "Price")
# Treatment n Mean SD Var
# <fct> <int> <dbl> <dbl> <chr>
#1 A 2 1.5 0.707 Price
#2 B 2 3.5 0.707 Price
例如:
df <- data.frame("Treatment" = c(rep("A", 2), rep("B", 2)), "Price" = 1:4, "Cost" = 2:5)
我想通过对所有变量的处理来汇总数据,并将它们放在一起,所以我定义了一个函数来首先对每个变量执行此操作,然后 rbind
稍后再对它们进行处理。
SummarizeFn <- function(x,y,z) {
df1 <- x %>% group_by(Treatment) %>%
summarize(n = n(), Mean = mean(y), SD = sd(y)) %>%
df1$Var = z # add a column to show which variable those statistics belong to.
}
SumPrice <- SummarizeFn(df, df$Price, "Price")
然而,结果是:
Treatment n Mean SD Var
<fct> <int> <dbl> <dbl> <chr>
1 A 2 2.5 1.29 Price
2 B 2 2.5 1.29 Price
它们是所有观察值的平均值和标准差,但不是按治疗分组的观察值。这里有什么问题?
如果我将代码从函数环境中取出,它完全可以正常工作。请帮助,谢谢。
如果你有更好的方法达到我的目的,那就太好了!谢谢!
这涉及到评价标准的问题。这很有趣,我刚刚写了一个article on the subject。这很难用 dplyr
传递字符串名称。如果您需要这样做,请使用 rlang::sym
(或 rlang::syms
)和 !!
(或 !!!
)
关于你的问题,我想data.table
给你一个简洁的解决方案
dt <- as.data.table(mtcars)
output <- dt[,lapply(.SD, function(d) return(list(.N,mean(d),sd(d)))),
.SDcols = c("mpg","qsec")]
output[,'stat' := c("observations","mean","sd")]
output
# output
# mpg qsec stat
# 1: 32 32 observations
# 2: 20.09062 17.84875 mean
# 3: 6.026948 1.786943 sd
我建议使用 lapply
的匿名函数,但您可以使用在摘要步骤之前定义的更复杂的函数。如果需要,请更改 .SDcols
以包含更多变量
当您在 dplyr
管道中将变量与 $
一起使用时,它们不遵循分组,并且就像它们应用于整个数据帧一样工作。除此之外,您可以使用 {{}}
来计算函数中的列名。
library(dplyr)
SummarizeFn <- function(x,y,z) {
x %>%
group_by(Treatment) %>%
summarize(n = n(), Mean = mean({{y}}), SD = sd({{y}}), Var = z)
}
SummarizeFn(df, Price, "Price")
# Treatment n Mean SD Var
# <fct> <int> <dbl> <dbl> <chr>
#1 A 2 1.5 0.707 Price
#2 B 2 3.5 0.707 Price