让我们说我有两个向量,
v1 = c(1,2,1,4,5,6,2,2,4,5,5,6)
v2 = c('lo', 'lo', 'la', 'la', 'la', 'li', 'li', 'li', 'li', 'lo', 'li', 'la')
我想按v1
中定义的组(lo, la, li
)取v2
的平均值。在没有循环的情况下,有效的方法是什么?
谢谢!
答案 0 :(得分:5)
这是tapply
的标准票价:
tapply(v1, v2, mean)
# la li lo
# 4.000000 3.800000 2.666667
另外,一个有趣的方法可能是:
xtabs(v1 ~ v2)/table(v2) ## sum divided by length
如果我猜测(其他人可以自由地进行基准测试),我认为tapply
和by
的性能非常接近案件。 xtabs
+ table
不应该太慢,但由于双重制表,肯定会慢一些。由于所有转换为data.frame
,尝试简化输出,等等,我认为aggregate
是最慢的方法。
答案 1 :(得分:3)
或aggregate
aggregate(v1 ~ v2, FUN = mean)
## v2 v1
## 1 la 4.000000
## 2 li 3.800000
## 3 lo 2.666667
答案 2 :(得分:2)
by
也适用于此。
> by(v1, v2, mean)
# v2: la
# [1] 4
# ---------------------------------------------------
# v2: li
# [1] 3.8
# ---------------------------------------------------
# v2: lo
# [1] 2.666667
可以用c()
包裹,将结果转换为矢量
> c(by(v1, v2, mean))
# la li lo
# 4.000000 3.800000 2.666667
或使用as.table
换行会将结果转换为表格。
答案 3 :(得分:2)
另一种方式是:
rapply(split(v1,v2), mean)
# la li lo
# 4.000000 3.800000 2.666667
set.seed(1)
v1 <- sample(100, 1000000, TRUE)
v2 <- paste0(LETTERS, sample(10, 1000000, TRUE))
fun1 <- function() rapply(split(v1,v2), mean)
fun2 <- function() tapply(v1, v2, mean)
fun3 <- function() aggregate(v1~v2, FUN=mean)
fun4 <- function() c(by(v1, v2, mean))
fun5 <- function() xtabs(v1~v2)/table(v2)
library(data.table) #included data.table method based on comments from @Ananda Mahto
fun6 <- function() data.table(v1, v2)[, mean(v1), by=v2]
library(dplyr)
fun7 <- function() {df <- data.frame(v1,v2)
df%>% group_by(v2)%>%
summarize(v1=mean(v1))}
library(microbenchmark)
microbenchmark(fun1(), fun2(), fun3(), fun4(), fun5(), fun6(), fun7())
#Unit: milliseconds
# expr min lq median uq max neval
# fun1() 61.49778 72.11014 93.77996 99.80158 507.7508 100
# fun2() 96.37805 112.37573 144.92092 161.54825 501.7165 100
# fun3() 10766.64464 12218.22933 16041.39458 16500.57674 24669.4982 100
# fun4() 119.83302 138.58920 175.82427 190.05616 730.4116 100
# fun5() 356.93513 445.36760 521.84018 594.67285 2117.1304 100
# fun6() 16.31299 18.67497 23.36138 25.72171 130.0437 100
# fun7() 78.79703 93.90406 119.69846 127.98684 454.6454 100