我有以下几点要处理。我有两个矩阵
a b c
b d d
a d b
和
1 2 3
4 5 6
7 8 9
我需要能够从第二个矩阵中确定指定的均值,如下所示:
现在这两个矩阵相当简单,我必须使用的矩阵在100 x 100的范围内。
欢迎任何想法
谢谢
答案 0 :(得分:3)
您可以在此处使用简单的tapply
。例如
#sample input
m1<-matrix(letters[c(1,2,1,2,4,4,3,4,2)], ncol=3)
m2<-matrix(1:9, byrow=T, ncol=3)
tapply(m2, m1, mean)
# a b c d
# 4.000000 5.000000 3.000000 6.333333
只要尺寸完全匹配,它们在矩阵中的事实并不重要。
答案 1 :(得分:3)
您可以将data.table
用于更大的数据集
library(data.table)
dt1 <- data.table(c(m1),c(m2)) #@MrFlick's datasets
dt1[,mean(V2), by=V1]
dt1[,list(V2=mean(V2)), by=V1]
# V1 V2
#1: a 4.000000
#2: b 5.000000
#3: d 6.333333
#4: c 3.000000
set.seed(45)
m1N <- matrix(sample(letters[1:20], 1e3*1e3, replace=TRUE), ncol=1e3)
m2N <- matrix(sample(0:40, 1e3*1e3, replace=TRUE), ncol=1e3)
system.time(res1 <- tapply(m2N, m1N, mean))
#user system elapsed
# 7.605 0.004 7.618
system.time({dt <- data.table(c(m1N), c(m2N))
setkey(dt, V1)
res2 <- dt[,mean(V2), by=V1]})
#user system elapsed
# 0.043 0.000 0.043
system.time(res3 <- unlist(lapply(split(m2N, m1N),mean)))
# user system elapsed
# 7.864 0.016 7.891
system.time(res4 <- sapply(sort(unique.default(m1N)), function(x) mean(m2N[m1N == x])))
# user system elapsed
# 1.007 0.012 1.021
答案 2 :(得分:1)
由于tapply
调用split
,在大型矩阵上,您可能会发现直接使用split
> unlist(lapply(split(m, m2), mean))
### or slightly slower: sapply(split(m, m2), mean)
# a b c d
# 4.000000 5.000000 3.000000 6.333333
,其中
> m <- structure(c(1L, 4L, 7L, 2L, 5L, 8L, 3L, 6L, 9L), .Dim = c(3L,3L))
> m2 <- structure(c("a","b","a","b","d","d","c","d","b"), .Dim = c(3L, 3L))
快速检查:
> f <- function() tapply(m, m2, mean)
> g <- function() unlist(lapply(split(m, m2), mean))
> library(microbenchmark)
> microbenchmark(f(), g(), times = 1e4L)
# Unit: microseconds
# expr min lq median uq max neval
# f() 421.083 432.2575 436.3975 440.503 3633.401 10000
# g() 267.119 277.1495 280.2180 283.982 69714.687 10000
答案 3 :(得分:0)
使用聚合,可能是最慢的......
aggregate(m2~m1,mean,data=data.frame(m1=c(m1),m2=c(m2)))
# m1 m2
# 1 a 4.000000
# 2 b 5.000000
# 3 c 3.000000
# 4 d 6.333333