1

多数の行(<90,000)と2列のみのマトリックス(この例ではポイントという名前)があります。

A B
1 10.1
2 9.2
3 4.5
1 8.9
1 0.7

列「A」からの一意の値と、それらの重複値に対応する列「B」からの値の平均のみを持つ別のマトリックスを作成したいと思います。結果:-

A B
1 6.56
2 9.20
3 4.50

現在、私はこれ(コードの下)を使用していますが、これには多くの時間がかかります。ですから、誰かがこれらの計算を高速化する方法を教えてくれれば、とてもありがたいです。

uniquedata<-points[which(!duplicated(points[,"A"])),]
reps<-points[which(duplicated(points[,"A"])),]
result<-list()
intensity<-list()
            for(i in c(1:length(uniquedata[,"A"]))){
                result[[i]]<-which(uniquedata[i,"A"]==reps[,"A"])
            }
            for(j in c(1:length(result))){
                if(length(result[[j]])!=0){
                    intensity[j]<-mean(c(reps[result[[j]],"B"],uniquedata[j,"B"]))
                }else{
                    intensity[j]<-uniquedata[j,"B"]
                }
            }
            points1<-cbind(uniquedata[,1],unlist(intensity))

私の理解では、私は多くのインデックス作成を行っているため、遅いのです。助けてくれてありがとう!

4

4 に答える 4

3

行列がある場合、に変換する必要がありdata.frameます。ここに使用するアプローチがありますrowsum

# assuming your matrix  is called M

 rowsum(M[,2],M[,1]) / rowsum(rep_len(1,nrow(M)), M[,1])

いくつかの適切なベンチマーク

using.by <- function() x <- by(df1$val, df1$name, mean) 
using.aggregate <- function() x <- aggregate(val ~ name, FUN = mean, data = df1)
using.ddply <- function() x <- ddply(df1, .(name), summarize, mu=mean(val))
using.tapply <- function() tapply(df1$val,df1$name,mean)
using.rowsum <- function () x <- rowsum(M[,2],M[,1]) / rowsum(rep_len(1,nrow(M)), M[,1])
using.data.table <- function() x <- DT[,mean(val),by=name]

library(microbenchmark)

set.seed(1)
n <- 1e6
df1 <- data.frame(name=sample(1:5, n, replace = TRUE),
                  val = runif(n))
M <- as.matrix(df1)
DT <- as.data.table(df1)

microbenchmark(using.by(), using.aggregate(), using.ddply(), 
               using.tapply(), using.rowsum(), using.data.table(), 
               times = 10)

Unit: milliseconds
#        expr               min         lq     median         uq        max neval
# using.by()          843.46550  854.22116  862.15995  868.75859  912.49406    10
# using.aggregate()  2416.37227 2451.60134 2482.25319 2498.54546 2501.58574    10
# using.ddply()       208.03686  209.29981  219.74203  253.46119  258.40935    10
# using.tapply()      819.30594  820.77757  830.07718  869.50280  987.24822    10
# using.rowsum()      192.36873  193.48971  194.42591  198.63762  238.91224    10
# using.data.table()   51.46841   52.37541   52.62934   53.05449   54.06227    10

当然のことながらdata.table、明確な勝者です!

于 2013-06-06T00:05:36.260 に答える
0

必須の data.table 回答:

set.seed(42)
m <- cbind(a=sample(1:3,1e4,TRUE),b=rnorm(1e4))

library(data.table)
DT <- as.data.table(m)
DT[,mean(b),by=a]

#    a          V1
# 1: 3 -0.01237034
# 2: 1  0.01064392
# 3: 2 -0.02411601
于 2013-06-05T14:36:19.560 に答える