2015-02-10 2 views
4

Я хочу, чтобы вычислить группу посредством переменной, но исключая фокусного ответчику:среднем по группе, удаление текущей строки

set.seed(1) 
dat <- data.table(id = 1:30, y = runif(30), grp = rep(1:3, each=10)) 

Первая запись (ответчик) должен иметь в среднем ... второй .. и т.:

mean(dat[c==1, y][-1]) 
mean(dat[c==1, y][-2]) 
mean(dat[c==1, y][-3]) 

Для второй группы же:

mean(dat[c==2, y][-1]) 
mean(dat[c==2, y][-2]) 
mean(dat[c==2, y][-3]) 

Я попытался это, но он не работает:

ex[, avg := mean(ex[, y][-.I]), by=grp] 

Любые идеи?

+0

Я знаю, что могу сделать это следующим образом: '' 'dat [, avg: = (sum (y) -y)/(. N-1), by = c]' '', но я хотел бы справиться с отсутствующими данными. – sdaza

+0

Возможно, 'sum (y, na.rm = TRUE)'? –

+0

Мне нужно было бы отрегулировать .N, чтобы оценить допустимое среднее значение, как при использовании среднего (y, na.rm = TRUE) – sdaza

ответ

2

Похоже ты большую часть пути туда и просто нужно не учитывать NA-х:

dat[, avg := (sum(y, na.rm=T) - ifelse(is.na(y), 0, y))/(sum(!is.na(y)) + is.na(y) - 1) 
    , by = grp] 

нет двойных петель или дополнительной памяти обязательный.

1

Если я правильно понять, я думаю, что это делает работу:

dat[, 
    .(id, y2=rep(y, .N), id2=rep(id, .N), id3=rep(id, each=.N)), by=grp  
][ 
    !(id2 == id3), 
    mean(y2), 
    by=.(id3, grp) 
] 

Первый шаг заключается в дублировать данные всей группы для каждого идентификатора, и указать, какой ряд мы хотим исключить из среднего , Второй шаг состоит в том, чтобы исключить строки, а затем группировать их по группам/id. Очевидно, что это не суперэффективная память, но она должна работать до тех пор, пока вы не ограничены памятью.

+0

, каждый ответчик (строка) должен иметь другое значение: среднее из всех значений группы, кроме этого одного из нынешних/координационных респондентов. – sdaza

+0

@sdaza, обновленный двухэтапным процессом, который, я думаю, делает то, что вы хотите. – BrodieG

+0

спасибо @BrodieG, я подумал, что может быть более простое решение с использованием data.table .... – sdaza

4

Вы можете попробовать это решение:

set.seed(1) 
dat <- data.table(id = 1:9, y = c(NA,runif(8)), grp = rep(1:3, each=3)) 

dat[, avg2 := sapply(seq_along(y),function(i) mean(y[-i],na.rm=T)), by=grp] 

dat 
# id   y grp  avg2 
# 1: 1  NA 1 0.3188163 
# 2: 2 0.2655087 1 0.3721239 
# 3: 3 0.3721239 1 0.2655087 
# 4: 4 0.5728534 2 0.5549449 
# 5: 5 0.9082078 2 0.3872676 
# 6: 6 0.2016819 2 0.7405306 
# 7: 7 0.8983897 3 0.8027365 
# 8: 8 0.9446753 3 0.7795937 
# 9: 9 0.6607978 3 0.9215325 
+3

этот вид двойной (тройной, если вы включаете цикл by by by by), будет экспоненциально медленным по мере увеличения размера данных – eddi

Смежные вопросы