2015-08-17 3 views
7

У меня есть таблица данных с большим количеством отсутствующих значений. Я хотел бы заполнить их, добавив или вычитая значения из доступных значений в таблице данных. В частности, рассмотрим эти данные:Заполнение значений NA на основе других значений в столбце

> test = data.table(id=c("A","A","A","A","A","B","B","B","B","B"), x=c(NA,NA,0,NA,NA,NA,NA,0,NA,NA)) 
> test 
    id x 
1: A NA 
2: A NA 
3: A 0 
4: A NA 
5: A NA 
6: B NA 
7: B NA 
8: B 0 
9: B NA 
10: B NA 

мне нужна операция, которая преобразует это в том, что:

id x 
1: A -2 
2: A -1 
3: A 0 
4: A 1 
5: A 2 
6: B -2 
7: B -1 
8: B 0 
9: B 1 
10: B 2 

основном версия na.locf, которая увеличивает последнее значение, а не повторять его.

ответ

8

Мы можем группировать по 'id' и принимать значение номера строки (seq_len(.N)) с положением (which) в 'x', где оно равно 0 (!x). Я обертываю as.numeric, так как столбец «x» равен numeric во входном наборе данных, но из разницы он преобразуется в «integer». Если есть столкновение в class при назначении (:=), в таблице данных будет отображаться ошибка, так как она должна соответствовать class.

test[, x:= as.numeric(seq_len(.N)-which(!x)), id] 
test 
# id x 
# 1: A -2 
# 2: A -1 
# 3: A 0 
# 4: A 1 
# 5: A 2 
# 6: B -2 
# 7: B -1 
# 8: B 0 
# 9: B 1 
#10: B 2 

!x иначе написано более ясно, как x==0. Он возвращает логический вектор TRUE/FALSE. Если значение NA, оно останется NA. Обернув which, мы получим значение 0. В этом примере это 3 для каждого идентификатора.

+1

Работает как очарование! Большое спасибо, я пробовал всевозможные комбинации locf и cumsum. – phildeutsch

+0

@phildeutsch Спасибо за отзыв. Рад узнать, что это работает. – akrun

+0

@akrun Я хотел бы знать, почему 'which (! X)' возвращает 3? – jazzurro