我有一个数据框记录了客户的详细消费金额,如下所示:
custid, value
1, 1
1, 3
1, 2
1, 5
1, 4
1, 1
2, 1
2, 10
3, 1
3, 2
3, 5
怎样使用平均值、最大值、中位数、标准差等计算特征?需要使用一些 apply 函数吗?如何操作?custid, mean, max,min,median,std
1, ....
2,....
3,....
library(dplyr)
dat%>%
group_by(custid)%>%
summarise(Mean=mean(value), Max=max(value), Min=min(value), Median=median(value), Std=sd(value))
# custid Mean Max Min Median Std
#1 1 2.666667 5 1 2.5 1.632993
#2 2 5.500000 10 1 5.5 6.363961
#3 3 2.666667 5 1 2.0 2.081666
针对更大的数据集,data.table
会更快。
setDT(dat)[,list(Mean=mean(value), Max=max(value), Min=min(value), Median=as.numeric(median(value)), Std=sd(value)), by=custid]
# custid Mean Max Min Median Std
#1: 1 2.666667 5 1 2.5 1.632993
#2: 2 5.500000 10 1 5.5 6.363961
#3: 3 2.666667 5 1 2.0 2.081666
除此之外,这里还有“doBy”包中的summaryBy
函数可供选择,你可以在其中指定要应用的list
函数。
library(doBy)
summaryBy(value ~ custid, data = mydf,
FUN = list(mean, max, min, median, sd))
# custid value.mean value.max value.min value.median value.sd
# 1 1 2.666667 5 1 2.5 1.632993
# 2 2 5.500000 10 1 5.5 6.363961
# 3 3 2.666667 5 1 2.0 2.081666
当然,您也可以坚持使用基本的R语言:myFun <- function(x) {
c(min = min(x), max = max(x),
mean = mean(x), median = median(x),
std = sd(x))
}
tapply(mydf$value, mydf$custid, myFun)
# $`1`
# min max mean median std
# 1.000000 5.000000 2.666667 2.500000 1.632993
#
# $`2`
# min max mean median std
# 1.000000 10.000000 5.500000 5.500000 6.363961
#
# $`3`
# min max mean median std
# 1.000000 5.000000 2.666667 2.000000 2.081666
cbind(custid = unique(mydf$custid),
do.call(rbind, tapply(mydf$value, mydf$custid, myFun)))
# custid min max mean median std
# 1 1 1 5 2.666667 2.5 1.632993
# 2 2 1 10 5.500000 5.5 6.363961
# 3 3 1 5 2.666667 2.0 2.081666
如果你想对所有或同一列使用更多的函数,可以使用dplyr
中的summarise_each
或mutate_each
:
require(dplyr)
dat %>%
group_by(custid) %>%
summarise_each(funs(max, min, mean, median, sd), value)
#Source: local data frame [3 x 6]
#
# custid max min mean median sd
#1 1 5 1 2.666667 2.5 1.632993
#2 2 10 1 5.500000 5.5 6.363961
#3 3 5 1 2.666667 2.0 2.081666
或者使用基于R的aggregate
的另一种选项:
aggregate(value ~ custid, data = dat, summary)
# custid value.Min. value.1st Qu. value.Median value.Mean value.3rd Qu. value.Max.
#1 1 1.000 1.250 2.500 2.667 3.750 5.000
#2 2 1.000 3.250 5.500 5.500 7.750 10.000
#3 3 1.000 1.500 2.000 2.667 3.500 5.000
我喜欢来自 psych
包的 describeBy()
函数。就像这样:
df <- structure(list(custid. = c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 3L,
3L, 3L), value = c(1L, 3L, 2L, 5L, 4L, 1L, 1L, 10L, 1L, 2L, 5L
)), .Names = c("custid.", "value"), class = "data.frame", row.names = c(NA,
-11L))
df
custid. value
1 1 1
2 1 3
3 1 2
4 1 5
5 1 4
6 1 1
7 2 1
8 2 10
9 3 1
10 3 2
11 3 5
# install.packages(c("psych"), dependencies = TRUE)
require(psych)
describeBy(df$value, df$custid.)
group: 1
vars n mean sd median trimmed mad min max range skew kurtosis se
1 1 6 2.67 1.63 2.5 2.67 2.22 1 5 4 0.21 -1.86 0.67
-----------------------------------------------------------------------
group: 2
vars n mean sd median trimmed mad min max range skew kurtosis se
1 1 2 5.5 6.36 5.5 5.5 6.67 1 10 9 0 -2.75 4.5
-----------------------------------------------------------------------
group: 3
vars n mean sd median trimmed mad min max range skew kurtosis se
1 1 3 2.67 2.08 2 2.67 1.48 1 5 4 0.29 -2.33 1.2
如果您更喜欢,也可以将其作为矩阵获取:
describeBy(df$value, df$custid., mat=T, skew = F)
item group1 vars n mean sd median min max range se
11 1 1 1 6 2.666667 1.632993 2.5 1 5 4 0.6666667
12 2 2 1 2 5.500000 6.363961 5.5 1 10 9 4.5000000
13 3 3 1 3 2.666667 2.081666 2.0 1 5 4 1.2018504
summarise_each()
已被弃用。请改用summarise_all()
、summarise_at()
或summarise_if()
。要在一组变量上映射funs
,请使用summarise_at()
。 - Alf Pascu