Рассчитать количество временных рядов изменения категорий подряд в R - PullRequest
0 голосов
/ 26 октября 2019

У меня есть следующий фрейм данных в R:

Row number   A   B   C   D   E   F   G   H   I   J
1                1   1   0   0   1   0   0   1   1
2                    1   0   0   0   1   0   0   1
3                1   0   0   0   1   0   0   1   1

Я пытаюсь подсчитать, сколько раз число меняется между 1 и 0, исключая нули

Результат яожидается, что это

Row Number    No of changes
----------    --------------
1                4
2                4
3                4

Объяснение для строки 1

В строке 1 A имеет значение NULL, поэтому мы исключаем, что

B и C имеют 1, что является нашимпервый набор значений.

D и E имеют 0, что является нашим вторым набором значений. Теперь Изменение = 1

F имеет наш третий набор значений, который равен 1. Теперь Изменение = 1 + 1

G и H имеют 0который является нашим третьим набором ценностей. Теперь Изменение = 1 + 1 + 1

У I и J есть 1, что является нашим четвертым набором значений. Теперь Изменить = 1 + 1 + 1 + 1 = 4

Ответы [ 2 ]

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

Вот такой подход. Я собираюсь в более длинный формат (от tidyr::pivot_longer), затем добавляю вспомогательный столбец, отмечающий, когда у нас есть изменение с 0 на 1 или с 1 на 0, и затем суммирую их по строкам.

library(tidyverse)            
df %>%
  # before tidyr 1.0, this would be   gather(col, value, -1)
  pivot_longer(-1, "col") %>%
  group_by(Row.number) %>%
  mutate(chg = value == 1 & lag(value) == 0 |
           value == 0 & lag(value) == 1) %>%
  summarize(no_chgs = sum(chg, na.rm = T))


# A tibble: 3 x 2
  Row.number no_chgs
       <int>   <int>
1          1       4
2          2       4
3          3       4

Примерданные:

df <- read.table(
  header = T, 
  stringsAsFactors = F,
  text = "'Row number'   A   B   C   D   E   F   G   H   I   J
            1            NA  1   1   0   0   1   0   0   1   1
            2            NA  NA  1   0   0   0   1   0   0   1
            3            NA  1   0   0   0   1   0   0   1   1")
0 голосов
/ 26 октября 2019

Вот решение :

library(data.table)
dt <- as.data.table(df)

dt[,
   no_change := max(rleid(na.omit(t(.SD)))) - 1,
   by = RowNumber
   ]
dt

Альтернативно, вот базовая версия:

apply(df[, -1],
      1,
      function(x) {
        complete_case = complete.cases(x)
        if (sum(complete_case) > 0) {
          return(length(rle(x[complete_case])$lengths) - 1)
        } else {
          return (0)
        }
        }
      )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...