귀하의 문제를 이해한다고 가정하면 aggregate()
대신 tapply()
을 사용하는 것이 좋습니다 (자세한 내용은 ?tapply
참조). 그러나, 최소한의 작업 예제는 매우 도움이 될 것입니다.
co.var <- function(x) (100*sd(x)/mean(x))
## Data with multiple repeated measurements.
## There are three things (ID 1, 2, 3) that
## are measured two times, twice each (val1 and val2)
myDF<-data.frame(ID=c(1,2,3,1,2,3),val1=c(20,10,5,25,7,2),
val2=c(19,9,4,24,4,1))
## Calculate coefficient of variation for each measurement set
myDF$coVar<-apply(myDF[,c("val1","val2")],1,co.var)
## Use tapply() instead of aggregate
mySel<-tapply(seq_len(nrow(myDF)),myDF$ID,function(x){
curSub<-myDF[x,]
return(x[which(curSub$coVar==max(curSub$coVar))])
})
## The mySel vector is then the vector of rows that correspond to the
## maximum coefficient of variation for each ID
myDF[mySel,]
편집 :
중 하나는 다음과 같습니다 빠른 방법이 있습니다. 그러나 40000x100 데이터 세트의 경우 위의 코드는 내 컴퓨터에서 16-20 초 밖에 걸리지 않았습니다.
# Create a big dataset
myDF <- data.frame(val1 = c(20, 10, 5, 25, 7, 2),
val2 = c(19, 9, 4, 24, 4, 1))
myDF <- myDF[sample(seq_len(nrow(myDF)), 40000, replace = TRUE), ]
myDF <- cbind(myDF, rep(myDF, 49))
myDF$ID <- sample.int(nrow(myDF)/5, nrow(myDF), replace = TRUE)
# Define a new function to work (slightly) better with large datasets
co.var.df <- function(x) (100*apply(x,1,sd)/rowMeans(x))
# Create two datasets to benchmark the two methods
# (A second method proved slower than the third, hence the naming)
myDF.firstMethod <- myDF
myDF.thirdMethod <- myDF
시간 원본 방법
startTime <- Sys.time()
myDF.firstMethod$coVar <- apply(myDF.firstMethod[,
grep("val", names(myDF.firstMethod))], 1, co.var)
mySel <- tapply(seq_len(nrow(myDF.firstMethod)),
myDF.firstMethod$ID, function(x) {
curSub <- myDF.firstMethod[x, ]
return(x[which(curSub$coVar == max(curSub$coVar))])
}, simplify = FALSE)
endTime <- Sys.time()
R> endTime-startTime
Time difference of 17.87806 secs
시간 두 번째 방법
startTime3 <- Sys.time()
coVar3<-co.var.df(myDF.thirdMethod[,
grep("val",names(myDF.thirdMethod))])
mySel3 <- tapply(seq_along(coVar3),
myDF[, "ID"], function(x) {
return(x[which(coVar3[x] == max(coVar3[x]))])
}, simplify = FALSE)
endTime3 <- Sys.time()
R> endTime3-startTime3
Time difference of 2.024207 secs
그리고 우리가 같은 결과를 얻을 수 있는지 확인 :
이
R> all.equal(mySel,mySel3)
[1] TRUE
추가가를 원래 게시물에서 변경,에서 편집 된 코드는 주어진 ID에 대해 가장 높은 CV를 가진 행이 여러 개있을 수 있다고 간주합니다. 따라서, 편집 된 코드의 결과, 당신은 mySel
또는 mySel3
객체를 unlist
해야한다 얻을 :`as.columnname`은 무엇입니까
myDF.firstMethod[unlist(mySel),]
myDF.thirdMethod[unlist(mySel3),]
를? – csgillespie