Группировка логики в R - PullRequest
       6

Группировка логики в R

1 голос
/ 01 октября 2019

Я пытаюсь выполнить группировку и не могу этого сделать

Подмножество данных, которое у меня есть, это

     name   value   group    num    range
     ----- -------  ------  ------  -------
      A      1        1      3      Jan2000-March2000
      A      0        2      1      Apr2000-Apr2000
      A      1        3      8      May2000-Dec2000
      A      0        4      1      Jan2001-Jan2001
      A      1        5      1      Feb2001-Feb2001
      A      0        6      9      March2001-Nov2001
      A      1        7      1      Dec2001-Dec2001
      A      0        8      1      Jan2002-Jan2002
      A      1        9      1      Feb2002-Feb2002
      A      0        10     2      March2002-April2002

Я хочу игнорировать группы со значениями 0 и 1которые находятся между группами со значением 1 и num> = 1 и объединяют их вместе.

Например, в приведенных выше данных я хотел бы игнорировать строки 2 и 4 и объединить их с группами значения 1, так какэти строки имеют значение 0 с numb = 1

Условием, с которого начинается новая группа, является либо строка со значением 0 и num> 1, либо строка со значением 1 и num> = 1

Вывод должен быть следующим:

     name   value   group    num    range
     ----- -------  ------  ------  -------
      A      1        1      14     Jan2000-Feb2001
      A      0        2      9      Mar2001-Nov2001
      A      1        3      3      Dec2001-Feb2002
      A      0        10     2      March2002-April2002

Это должно быть сделано для более чем 1 имен, таких как B, C, D и т. Д.

1 Ответ

2 голосов
/ 01 октября 2019

Я думаю, что у меня есть рабочее решение для этого (хотя оно еще не учитывает другие name с) - это кажется довольно сложной проблемой. Это, вероятно, не особенно эффективное решение, так как он находит одну строку для свертывания, сворачивает ее, а затем снова проверяет весь набор данных и проходит через процесс, пока не останется больше строк для свертывания. Если есть более эффективные способы сделать это, я бы хотел увидеть их:

# Identify which rows are "between" rows that can be collapsed
get_between_info = function(data) {
    data %>%
        mutate(outer_row = value == 1 & num >= 1,
               inner_row = value == 0 & num == 1,
               between_row = inner_row & lead(outer_row) & lag(outer_row))
}

df = df %>%
    get_between_info()

while (any(df$between_row)) {
    collapse_group = which(df$between_row)[1] + c(-1, 0, 1)
    collapsed = summarise(df[collapse_group, ], 
                          name = first(name),
                          value = 1, 
                          group = first(group), 
                          num = sum(num),
                          range = paste0(
                              str_split(range[1], "-")[[1]][1],
                              "-",
                              str_split(range[n()], "-")[[1]][2]
                           ))
    before = df %>% filter(row_number() < collapse_group[1])
    after = df %>% filter(row_number() > collapse_group[3])

    df = bind_rows(before, collapsed, after)
    df = df %>% get_between_info()
}

Вывод (я не понимаю логику определения чисел group, поэтому мои отличаются):

> df
  name value group num               range outer_row inner_row between_row
1    A     1     1  14     Jan2000-Feb2001      TRUE     FALSE       FALSE
2    A     0     6   9   March2001-Nov2001     FALSE     FALSE       FALSE
3    A     1     7   3     Dec2001-Feb2002      TRUE     FALSE       FALSE
4    A     0    10   2 March2002-April2002     FALSE     FALSE       FALSE

Свернувшийся код, вероятно, можно было бы очистить, сначала разбив столбец range на отдельные столбцы range_start и range_end (перед началом любого из этих процессов) - это сделало бы генерацию свернутого df намного чище.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...