Использование R для подсчета последовательных вхождений числа и сколько времени длится каждое вхождение? - PullRequest
0 голосов
/ 30 мая 2020

У меня есть большой набор данных (dt), в котором есть столбец времени (где время в секундах) и столбец, в котором записывается 1, когда некоторые другие переменные соответствуют определенному значению, и 0, когда они этого не делают, например :

time (s) var
0        1   
0.3      1
0.6      0
0.9      0
1.2      1
1.5      1
1.8      0

Часть 1) я хочу подсчитывать каждый раз, когда 1 повторяется как уникальное вхождение (более двух раз) в столбце подсчета, который будет выглядеть следующим образом:

time (s) var count
0        1   1
0.3      1   1
0.6      0   0
0.9      0   0
1.2      1   2
1.5      1   2
1.8      0   0

где каждое событие в одном и том же поединке будет иметь один и тот же номер, а где 0 означает, что счет не ведется.

Для части 1 у меня это пока есть, но я хотел бы, чтобы он печатал каждое уникальное вхождение как счетчик в столбце, чего он не делает:

with(rle(dt$var), sum(lengths[values] > 2))

Часть 2) Я также хочу знать, сколько времени длится каждое событие. (У меня также есть реплицируемый столбец, который имеет значение 1 для каждой строки)

Я пробовал это для расчета части 2, но это не работает ...

var_time <- dt %>%
  group_by(replicate) %>%
  mutate(var_time = cumsum(var != lag(var, default = ""))) %>%
  group_by(var, time) %>%
  summarise(start = min(time),
            end   = max(time),
            var = sum(var))

Ответы [ 2 ]

1 голос
/ 30 мая 2020

Вы можете использовать rle, чтобы получить ответ на первую часть.

dt$count <- with(rle(dt$var), rep(values * cumsum(values & lengths >= 2),lengths))

dt
#  time var count
#1  0.0   1     1
#2  0.3   1     1
#3  0.6   0     0
#4  0.9   0     0
#5  1.2   1     2
#6  1.5   1     2
#7  1.8   0     0
0 голосов
/ 30 мая 2020

Вариант с data.table

library(data.table)
setDT(df1)[, count := rleid(var) * var][count != 0, 
     count := match(count, unique(count))][]
#     time var count
#1:  0.0   1     1
#2:  0.3   1     1
#3:  0.6   0     0
#4:  0.9   0     0
#5:  1.2   1     2
#6:  1.5   1     2
#7:  1.8   0     0

Или с base R с использованием rle/inverse.rle

df1$count <- inverse.rle(within.list(rle(df1$var), 
      values[as.logical(values)] <- seq_along(values[as.logical(values)])))

data

df1 <- data.frame(time = c(0, 0.3, 0.6, 0.9, 1.2, 1.5, 1.8), var = c(1, 1, 0, 0, 1, 1, 0))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...