2017-02-15 3 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の$のCUSTOMERID、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"] 

これはなる、と彼はそれぞれの2回のスキャンを行うことから、上記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 
関連する問題