2017-02-10 10 views
0

У меня есть data.frame, там я определил строку, у которой есть неправильные/отсутствующие данные.Ранг по пробелам в данных

Мне нужно посчитать последовательные отсутствующие значения. То, что мне не хватает, - это функция, которая может быть ранжирована, но ранг перезапускается на каждом промежутке и увеличивается с каждым разрывом подряд.

В основном мой кадр данных выглядит следующим образом:

df <- data.frame(Date = as.Date("2017-02-10") + 1:10, Missing = c(F,F,T,F,T,T,T,F,T,T)) 

Я хочу, чтобы получить это:

data.frame(Date = as.Date("2017-02-10") + 1:10, Missing = c(F,F,T,F,T,T,T,F,T,T), 
      Rank = c(0,0,1,0,1,2,3,0,1,2)) 
#   Date Missing Rank 
# 1 2017-02-11 FALSE 0 
# 2 2017-02-12 FALSE 0 
# 3 2017-02-13 TRUE 1 
# 4 2017-02-14 FALSE 0 
# 5 2017-02-15 TRUE 1 
# 6 2017-02-16 TRUE 2 
# 7 2017-02-17 TRUE 3 
# 8 2017-02-18 FALSE 0 
# 9 2017-02-19 TRUE 1 
# 10 2017-02-20 TRUE 2   

Я знаком с dplyr и я попытался с помощью cummax но не перезапускает счетчик, я не знаю, как сбросить его до нуля:

library(dplyr) 
df %>% mutate(Rank = if_else(Missing == T, cummax(Rank), 0)) 

Я начинаю интересно ли это потребует цикл.

ответ

4

Вам нужно создать кумулятивную сумму Missing колонки, , сгруппированных по кумулятивной сумме всех FALSE значений:

library(dplyr) 
test.df %>% group_by(group = cumsum(Missing == FALSE)) %>% 
    mutate(Rank = cumsum(Missing)) 
#   Date Missing group Rank 
#  <date> <lgl> <int> <int> 
#1 2017-02-11 FALSE  1  0 
#2 2017-02-12 FALSE  2  0 
#3 2017-02-13 TRUE  2  1 
#4 2017-02-14 FALSE  3  0 
#5 2017-02-15 TRUE  3  1 
#6 2017-02-16 TRUE  3  2 
#7 2017-02-17 TRUE  3  3 
#8 2017-02-18 FALSE  4  0 
#9 2017-02-19 TRUE  4  1 
#10 2017-02-20 TRUE  4  2 

Это работает, потому что логические значения представлены в виде 0 х и 1 " под капотом.

+1

Попеременно, 'Rank = row_number() - 1L' – Frank

+0

Wow это не имело бы место для меня, чтобы построить такие группы. Это работает как шарм. спасибо – sgp667

0

Вот альтернативный подход с использованием data.table

library(data.table) 
setDT(df)[, Rank := cumsum(Missing), rleid(Missing)] 

df 
#   Date Missing Rank 
# 1: 2017-02-11 FALSE 0 
# 2: 2017-02-12 FALSE 0 
# 3: 2017-02-13 TRUE 1 
# 4: 2017-02-14 FALSE 0 
# 5: 2017-02-15 TRUE 1 
# 6: 2017-02-16 TRUE 2 
# 7: 2017-02-17 TRUE 3 
# 8: 2017-02-18 FALSE 0 
# 9: 2017-02-19 TRUE 1 
#10: 2017-02-20 TRUE 2