2016-06-04 3 views
1

요약 통계를 그룹별로 얻는 방법의 속도를 비교하려고했습니다. 그러나 microbenchmark을 실행할 때 오류가 발생합니다. 오류 상태 :datatable, tapply, aggregate, ave 및 dplyr이있는 마이크로 벤치 마크

Error in bmerge(i, x, leftcols, rightcols, io, xo, roll, rollends, nomatch, : 
    x.'TRIAL_INDEX' is a character column being joined to i.'TRIAL_INDEX' which is type 'integer'. Character columns must join to factor or character columns. 

나는 잘 모르겠지만, 내가 data.table 변수 TRIAL_INDEXattribute 변화라고 생각한다. 비슷한 질문에 대해 Stack Overflow을 검색 할 때 일부 패키지간에 충돌이 있었던 것 같습니다.

해결 방법이 있습니까? TRIAL_INDEX의 속성을 integer으로 다시 변경하거나 microbenchmark 기능이 작동하도록 다른 조치를 취할 수 있습니까? 또는 내가 볼 수없는 오류가 발생했을 수 있습니다.

다음은 비교하려고하는 다섯 가지 기능이있는 코드입니다. 이 함수들의 서브 세트를 실행함으로써, 나는 얼마나 빨리 함수가 ave인지에 감명 받았습니다. 당신이 한 수

library(microbenchmark) 
library(dplyr) 
library(data.table) 

poo <- read.table(text = ' 
    TRIAL_INDEX  RIGHT_PUPIL_SIZE 
      1     10 
      1     8 
      1     6 
      1     4 
      1     NA 
      2     1 
      2     2 
      2     NA 
      2     4 
      2     5 
', header = TRUE, stringsAsFactors = FALSE, na.strings = "NA") 

tapply.function <- function(x) { 

    my.summary <- as.data.frame(do.call("rbind", 
        tapply(poo$RIGHT_PUPIL_SIZE, poo$TRIAL_INDEX, 
        function(x) c(index.mean = mean(x, na.rm = TRUE), 
            index.sd = sd(x, na.rm = TRUE))))) 

    my.summary$TRIAL_INDEX <- rownames(my.summary) 

    poo2 <- merge(poo, my.summary, by = 'TRIAL_INDEX') 

    return(poo2) 

} 

str(tapply.function(poo)) 

aggregate.function <- function(x) { 

    my.summary <- with(poo, aggregate(RIGHT_PUPIL_SIZE, by = list(TRIAL_INDEX), 
         FUN = function(x) {c(index.mean = mean(x, na.rm = TRUE), 
               index.sd = sd(x, na.rm = TRUE))})) 

    my.summary <- do.call(data.frame, my.summary) 

    colnames(my.summary) <- c('TRIAL_INDEX', 'index.mean', 'index.sd') 

    poo2 <- merge(poo, my.summary, by = 'TRIAL_INDEX') 

    return(poo2) 

} 

str(aggregate.function(poo)) 

ave.function <- function(x) { 

    index.mean <- ave(poo$RIGHT_PUPIL_SIZE, poo$TRIAL_INDEX, FUN = function(x) mean(x, na.rm = TRUE)) 
    index.sd <- ave(poo$RIGHT_PUPIL_SIZE, poo$TRIAL_INDEX, FUN = function(x) sd(x, na.rm = TRUE)) 

    poo2 <- data.frame(poo, index.mean, index.sd) 

    return(poo2) 

} 

str(ave.function(poo)) 

dplyr.function <- function(x) { 

    my.summary <- poo %>% 
     group_by(TRIAL_INDEX) %>% 
     summarise(index.mean = mean(RIGHT_PUPIL_SIZE, na.rm = TRUE), 
        index.sd = sd(RIGHT_PUPIL_SIZE, na.rm = TRUE)) 

    poo2 <- merge(poo, as.data.frame(my.summary), by = 'TRIAL_INDEX') 

    return(poo2) 

} 

str(dplyr.function(poo)) 

data.table.function <- function(x) { 

    my.summary <- data.frame(setDT(poo)[, .(index.mean = mean(RIGHT_PUPIL_SIZE, na.rm = TRUE), 
               index.sd = sd(RIGHT_PUPIL_SIZE, na.rm = TRUE)), 
          .(TRIAL_INDEX)]) 

    poo2 <- merge(poo, my.summary, by = 'TRIAL_INDEX') 

    return(poo2) 

} 

str(data.table.function(poo)) 

# this does not work 
microbenchmark( tapply.function(poo), 
       aggregate.function(poo), 
         ave.function(poo), 
        dplyr.function(poo), 
       data.table.function(poo), times = 1000) 

답변

2

간단한 테스트 등 당신의 기능에 cat("In tapply"), cat("In ave")을 추가하고 디버깅 times = 1L 다시 그것을 실행하는 것입니다. 그를하는

,이 얻을 :

> microbenchmark( tapply.function(poo), 
+     aggregate.function(poo), 
+     ave.function(poo), 
+     dplyr.function(poo), 
+     data.table.function(poo), times = 1) 
In dplyr 
In tapply 
Error in bmerge(i, x, leftcols, rightcols, io, xo, roll, rollends, nomatch, : 
    x.'TRIAL_INDEX' is a character column being joined to i.'TRIAL_INDEX' which is type 'integer'. Character columns must join to factor or character columns. 

오류가 tapply 기능에서 발생합니다. ...

my.summary <- as.data.frame(do.call("rbind", tapply(poo$RIGHT_PUPIL_SIZE, 
        poo$TRIAL_INDEX, function(x) c(index.mean = mean(x, na.rm = 
         TRUE), index.sd = sd(x, na.rm = TRUE))))) 
my.summary$TRIAL_INDEX <- rownames(my.summary) 

땡 땡 땡 .. 우리가했습니다 승자

str(my.summary) 
# 'data.frame': 2 obs. of 3 variables: 
# $ index.mean : num 7 3 
# $ index.sd : num 2.58 1.83 
# $ TRIAL_INDEX: chr "1" "2" ## <~~~ char type 

을 그리고는 이유입니다 :

의 그 함수의 처음 두 행을 살펴 보자 오류 메시지는 다음에 merge입니다. 왜? (개체 btw에 이상한 이름)을 에 사용하고 있기 때문에 poo (?!?) 으로 수정했습니다. 그리고 모든 후속 테스트는 해당 객체를 data.table로 사용합니다. 당신의 data.table.function()의 끝에서

의 ANS을 반환하기 전에, setDF(poo) 사용하거나 대신 그 기능에 as.data.table(poo)을 사용하고, 벤치 마크 as.data.table(poo)의 시간은 별도로 우리는 data.table의 타이밍에서 변환 시간을 공제 할 수 있도록 기능.

이 모든 것을 제외하고 10 개 행에서 data.frame -> data.table -> data.frame의 유형 변환에서 오버 헤드를 측정 할 가능성이 큽니다. 나는 당신이 ns/us 타이밍에서 얻을 수있는 의미있는 결론을 확신하지 못합니다. (이 작업을 1,000 번 또는 10,000 번 반복하지 않는 한).

+0

감사합니다. 나는 당신의 제안을 구현하려고합니다. 나는'TRIAL_INDEX'이 정수라고 말하는'str (tapply.function (poo))'를 사용했습니다. 그러나 그것이 나의 이해의 한계였다. 나는 '푸우'가 특별한 이름 이라는데 동의한다. 그것은이 게시물에서 온다 : http://stackoverflow.com/questions/37623544/how-to-remove-outliers-efficiently-for-each-trial/37624320#37624320 그리고 나는 그것을 변경하지 않았다. –

+2

걱정할 필요가 없습니다. base R의 merge가 다른 타입에 대해 경고/에러를 내지 않기 때문에'tapply()'함수는 data.frames에서 잘 작동 할 것입니다. 하지만 data.table의 병합은 .. (그리고 나는 더 좋다고 생각합니다). data.table.function()이 한 번 실행되면 실패하기 시작합니다.벤치마킹을하기 전에 Microbenchmark 셔플/샘플 기능을 사용하면'times = 1L'로 운이 좋았다고 생각합니다. 아마도'times = 2L'이 더 적절할 것입니다. – Arun