2015-08-19 3 views
3

Мне нужно получить номера строк для явных строк, сгруппированных по id. Скажем dataframe (ДФ) выглядит следующим образом:номера строк для явных строк в r

id a b 
3 2 NA 
3 3 2 
3 10 NA 
3 21 0 
3 2 NA 
4 1 5 
4 1 0 
4 5 NA 

Мне нужно создать еще один столбец, который будет давать числовую последовательность строк за исключением случая, когда b == 0.

желаемый результат:

id a b row 
3 2 NA 1 
3 3 2 2 
3 10 NA 3 
3 21 0 - 
3 2 NA 4 
4 1 5 1 
4 1 0 - 
4 5 NA 2 

Я использовал dplyr, но не в состоянии достичь того же, Мой код:

df <- df %>% 
     group_by(id) %>% 
     mutate(row = row_number(id[b != 0])) 

Пожалуйста, предложить некоторые лучший способ сделать это.

+2

'мутируют (строка = IfElse (! Is.na (б), Н. А., cumsum (is.na (б))))' ' – Khashaa

+0

Или мутируют (строка = заменить (cumsum (is.na (б)) , b == 0, "-")) ', но вы должны заметить, что, помещая« - »в числовой столбец, он будет принудительно применен к символу. –

+0

обновленный вопрос, может быть какое-то числовое значение в b –

ответ

7

Я бы предложил использовать пакет data.table для его хорошей возможности в работе на подмножествах и, таким образом, избежать неэффективных операций, таких как ifelse или оценить весь набор данных. Кроме того, лучше держать вас в вектор в числовом классе (для будущих операций), таким образом NA будет, вероятно, предпочтительнее - (характер), вот одно из возможных решений

library(data.table) 
setDT(df)[is.na(b) | b != 0, row := seq_len(.N), by = id] 
# id a b row 
# 1: 3 2 NA 1 
# 2: 3 3 2 2 
# 3: 3 10 NA 3 
# 4: 3 21 0 NA 
# 5: 3 2 NA 4 
# 6: 4 1 5 1 
# 7: 4 1 0 NA 
# 8: 4 5 NA 2 

Идея заключается в том, чтобы работать только в строках, где is.na(b) | b != 0 и генерировать последовательность каждого размера группы (.N) при обновлении rowна месте (с использованием :=). По умолчанию все остальные строки будут присвоены NA.

+1

'! B% in% 0' будет короче .. – Arun

+0

Argh, обратно к старым аргументам' == 'vs'% in% 'vs join http://stackoverflow.com/a/16222108 (связанным с предложением Аруна в выше). – Frank