2017-02-15 12 views
1
Customer id Year  a  b 
1    2000  10  2 
1    2001  5  3 
1    2002  NA  4 
1    2003  NA  5 
2    2000  2  NA 
2    2001  NA  4 
2    2002  4  NA 
2    2003  8  10 
3    2000  9  NA 
3    2001  10  NA 
3    2002  11  12 
+2

은'zoo'는 '... 것은 이러한 유형의 동물원 :: na.aggregate (d [C ("A", "B"), D $으로의 고객 ID, FUN = 중앙값)에 유용한 기능을 가진다 ' – user20650

답변

3

당신이 할 수있는 다음

require(dplyr) 
impute_median <- function(x){ 
    ind_na <- is.na(x) 
    x[ind_na] <- median(x[!ind_na]) 
    as.numeric(x) 
} 

dat %>% 
    group_by(Customer_id) %>% 
    mutate_at(vars(a, b), impute_median) 
+0

여기서'dplyr'와'magrittr'의 구현을 좋아하지만, 실행했을 때 정확한 중간 값을 반환하지 않는 것 같습니다. –

+0

신경 쓰지 마라, 나는 그 질문을 잘못 해석했다. –

0

data.table 솔루션 :

dat[, `:=` (a= ifelse(is.na(a), median(a, na.rm=TRUE), a) 
      b= ifelse(is.na(a), median(b, na.rm=TRUE), b)), by= "Customer_id"] 

이 될, 그는 각각의 두 개의 스캔을 수행하기 때문에, Floo0의 솔루션 위의 빠른 @보다입니다한다 기둥.

library(data.table) 
library(microbenchmark) 
set.seed(1234L) 

dat <- data.frame(id= rep(c(1:10), each= 100), 
        a= rnorm(1000), 
        b= rnorm(1000)) 

dat[,2:3] <- apply(dat[,2:3], 2, function(j) { 
    idx <- sample.int(1000, 100, replace=F) 
    j[idx] <- NA 
    return(j) 
}) 

require(dplyr) 
impute_median <- function(x){ 
    ind_na <- is.na(x) 
    x[ind_na] <- median(x[!ind_na]) 
    as.numeric(x) 
} 


dat2 <- setDT(dat) 

microbenchmark(Floo0= {dat %>% 
    group_by(id) %>% 
    mutate_at(vars(a, b), impute_median)}, 
    alex= {dat[, `:=` (a= ifelse(is.na(a), median(a, na.rm=TRUE), a), 
         b= ifelse(is.na(a), median(b, na.rm=TRUE), b)), by= "id"]}) 

Unit: milliseconds 
    expr  min  lq  mean median  uq  max neval cld 
Floo0 3.703411 3.851565 4.216543 3.947955 4.167063 7.67234 100 b 
    alex 1.265559 1.430002 1.704431 1.486006 1.687710 5.21753 100 a