通过在不同向量中定义的因子来获取一个向量的平均值

时间:2014-07-20 18:52:39

标签: r

让我们说我有两个向量,

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的平均值。在没有循环的情况下,有效的方法是什么?

谢谢!

4 个答案:

答案 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

如果我猜测(其他人可以自由地进行基准测试),我认为tapplyby的性能非常接近案件。 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