Всякий раз, когда скорость равна 0, суммируйте время, в течение которого она остается равной нулю (r)

#r

Вопрос:

Это мой первый раз здесь. Мне самому удалось пройти большую часть этого кода, но я застрял на этой последней части.

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

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

Заранее спасибо за вашу помощь!

     time distance slope `rolling velocity avg` `clean velocity`
   <dbl>    <dbl> <dbl>                  <dbl>            <dbl>
 1  2.51     0    0                     0.164             0    
 2  3.55     0    0.168                 0.327             0.327
 3  4.56     0.17 0.486                 0.450             0.450
 4  5.61     0.68 0.654                 0.567             0.567
 5  6.65     1.36 0.490                 0.527             0.527
 6  7.69     1.87 0.638                 0.364             0.364
 7  8.74     2.54 0.327                 0.241             0.241
 8  9.78     2.88 0                     0.0817            0    
 9 10.8      2.88 0                     0                 0    
10 11.9      2.88 0                     0.0810            0    
11 12.9      2.88 0                     0.285             0.285
12 14.0      2.88 0.324                 0.449             0.449
13 15        3.22 0.817                 0.651             0.651
14 16.0      4.07 0.654                 0.731             0.731
15 17.1      4.75 0.810                 0.649             0.649
 

Редактировать:
Я бы добавил 6-ю колонку под названием «период остановлен». В этом столбце будет указано время, прошедшее с начала нулей до тех пор, пока оно не станет ненулевым значением. Было бы разумно поставить его в конце остановленного периода. Например, строки с 8 по 10 не имеют скорости, поэтому он вычитает [10,1] — [8,1] и выведет время, прошедшее с [10,6]. Каждый раз, когда появляется новая последовательность нулей, она будет делать то же самое, пока не достигнет конца тиббла

Комментарии:

1. Добро пожаловать в StackOverflow! Чтобы иметь возможность помочь вам, не могли бы вы, пожалуйста, сообщить, как вы ожидаете, что ваш результат будет выглядеть?

2. Привет, Витсе, спасибо за радушный прием! Я бы добавил 6-ю колонку под названием «период остановлен». В этом столбце будет указано время, прошедшее с начала нулей до тех пор, пока оно не станет ненулевым значением. Было бы разумно поставить его в конце остановленного периода. Например, строки с 8 по 10 не имеют скорости, поэтому он вычитает [10,1] — [8,1] и выведет время, прошедшее с [10,6]. Каждый раз, когда появляется новая последовательность нулей, она будет делать то же самое, пока не достигнет конца тиббла

3. Комментарии не следует использовать для уточнения вопросов. вопрос должен стоять сам по себе. Отредактируйте вопрос, чтобы уточнить его, а затем добавьте комментарий, объясняющий, какие изменения были внесены или где искать в вопросе, чтобы увидеть разъяснения. Кроме того, вопрос должен показывать ожидаемый ответ точно так, как он был бы получен из R.

Ответ №1:

Это то, что вы ищете?

 library(data.table)
library(dplyr)

df %>%
  mutate(lead = lead(time)) %>%
  group_by(grp = rleid(`clean velocity`)) %>%
  mutate(StopDuration = (`clean velocity` == 0) * (row_number() == 1) * (max(lead) - time)) %>%
  ungroup() %>%
  select(-grp, -lead)
 

Приведем следующую таблицу:

 # A tibble: 15 x 6
    time distance slope `rolling velocity avg` `clean velocity` StopDuration
   <dbl>    <dbl> <dbl>                  <dbl>            <dbl>        <dbl>
 1  2.51     0    0                     0.164             0             1.04
 2  3.55     0    0.168                 0.327             0.327         0   
 3  4.56     0.17 0.486                 0.45              0.45          0   
 4  5.61     0.68 0.654                 0.567             0.567         0   
 5  6.65     1.36 0.49                  0.527             0.527         0   
 6  7.69     1.87 0.638                 0.364             0.364         0   
 7  8.74     2.54 0.327                 0.241             0.241         0   
 8  9.78     2.88 0                     0.0817            0             3.12
 9 10.8      2.88 0                     0                 0             0   
10 11.9      2.88 0                     0.081             0             0   
11 12.9      2.88 0                     0.285             0.285         0   
12 14        2.88 0.324                 0.449             0.449         0   
13 15        3.22 0.817                 0.651             0.651         0   
14 16        4.07 0.654                 0.731             0.731         0   
15 17.1      4.75 0.81                  0.649             0.649        NA  
 

Комментарии:

1. Я так думаю! За исключением того, что, когда я снова поднимаю тиббл, столбца остановки там нет. Это также произошло с ответом @denisafonin

2. Если вы хотите добавить новую таблицу в глобальную среду, вам необходимо использовать df -> df %>% rest of code

Ответ №2:

Предположим, что входные данные воспроизводимы в Примечании в конце.

В комментарии к постеру вопроса указано, что последним элементом нового столбца для каждой последовательной группы нулей должна быть разница между первым и последним временем, т. е. разница между максимальным и минимальным временем в этой группе. Другие значения не были определены, но мы предполагаем, что любой неопределенный компонент должен быть равен 0. rleid из данных.таблица используется для присвоения каждой группе последовательных элементов уникального идентификатора (поочередно используется groupid из пакета свернуть), и мы умножаем clean_velocity==0 на ноль любой элемент, который не соответствует 0.

 library(data.table) # rleid

DF[10,1] - DF[8,1] # check: expected value in position 10,6 of result
## [1] 2.12

FUN <- function(x) c(rep(0, length(x)-1), diff(range(x)))
transform(DF, stopped = 
  (clean_velocity == 0) * (ave(time, rleid(clean_velocity), FUN = FUN)))

    time distance slope rolling_velocity_avg clean_velocity stopped
1   2.51     0.00 0.000               0.1640          0.000    0.00
2   3.55     0.00 0.168               0.3270          0.327    0.00
3   4.56     0.17 0.486               0.4500          0.450    0.00
4   5.61     0.68 0.654               0.5670          0.567    0.00
5   6.65     1.36 0.490               0.5270          0.527    0.00
6   7.69     1.87 0.638               0.3640          0.364    0.00
7   8.74     2.54 0.327               0.2410          0.241    0.00
8   9.78     2.88 0.000               0.0817          0.000    0.00
9  10.80     2.88 0.000               0.0000          0.000    0.00
10 11.90     2.88 0.000               0.0810          0.000    2.12
11 12.90     2.88 0.000               0.2850          0.285    0.00
12 14.00     2.88 0.324               0.4490          0.449    0.00
13 15.00     3.22 0.817               0.6510          0.651    0.00
14 16.00     4.07 0.654               0.7310          0.731    0.00
15 17.10     4.75 0.810               0.6490          0.649    0.00
 

С другой стороны, это может быть выражено с помощью dlyr, как это, где FUN сверху.

 library(data.table)
library(dplyr)

DF %>%
  group_by(g = rleid(clean_velocity)) %>%
  mutate(stopped = (clean_velocity == 0) * FUN(time)) %>%
  ungroup %>%
  select(-g)
 

Примечание

 DF <-
structure(list(time = c(2.51, 3.55, 4.56, 5.61, 6.65, 7.69, 8.74, 
9.78, 10.8, 11.9, 12.9, 14, 15, 16, 17.1), distance = c(0, 0, 
0.17, 0.68, 1.36, 1.87, 2.54, 2.88, 2.88, 2.88, 2.88, 2.88, 3.22, 
4.07, 4.75), slope = c(0, 0.168, 0.486, 0.654, 0.49, 0.638, 0.327, 
0, 0, 0, 0, 0.324, 0.817, 0.654, 0.81), rolling_velocity_avg = c(0.164, 
0.327, 0.45, 0.567, 0.527, 0.364, 0.241, 0.0817, 0, 0.081, 0.285, 
0.449, 0.651, 0.731, 0.649), clean_velocity = c(0, 0.327, 0.45, 
0.567, 0.527, 0.364, 0.241, 0, 0, 0, 0.285, 0.449, 0.651, 0.731, 
0.649)), class = "data.frame", row.names = c("1", "2", "3", "4", 
"5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15"))
 

Комментарии:

1. Спасибо вам за вашу помощь! Этот работает хорошо. У меня есть один последующий глупый вопрос. Вывод после того, как я выполню ваш код, он даст мне столбец с надписью «остановлено». Это именно то, что я ищу. Однако, если я введу имя своего тиббла, чтобы еще раз взглянуть, колонка исчезнет. Есть ли способ сохранить колонку там? Я думал, что mutate() означает, что он должен быть прикреплен к концу тиббла.

2. Команды в конвейере не изменяют свои входные данные. Если вы хотите сохранить результат, вам нужно назначить его переменной. DF2 <- DF %>% ...

Ответ №3:

Если я правильно понял, это то, что я могу предложить.

Шаг 1. Создайте новый столбец, рассчитанный как разница во времени между каждой последовательной строкой (при условии, что они отсортированы правильно).:

 library(dplyr)

df %>%
  mutate(t_lead = lead(time)-time)

    time distance slope rolling_velocity_avg clean_velocity t_lead
1   2.51     0.00 0.000               0.1640          0.000   1.04
2   3.55     0.00 0.168               0.3270          0.327   1.01
3   4.56     0.17 0.486               0.4500          0.450   1.05
4   5.61     0.68 0.654               0.5670          0.567   1.04
5   6.65     1.36 0.490               0.5270          0.527   1.04
6   7.69     1.87 0.638               0.3640          0.364   1.05
7   8.74     2.54 0.327               0.2410          0.241   1.04
8   9.78     2.88 0.000               0.0817          0.000   1.02
9  10.80     2.88 0.000               0.0000          0.000   1.10
10 11.90     2.88 0.000               0.0810          0.000   1.00
11 12.90     2.88 0.000               0.2850          0.285   1.10
12 14.00     2.88 0.324               0.4490          0.449   1.00
13 15.00     3.22 0.817               0.6510          0.651   1.00
14 16.00     4.07 0.654               0.7310          0.731   1.10
15 17.10     4.75 0.810               0.6490          0.649     NA
 

Шаг 2: Отфильтруйте clean_velocity == 0 и подведите итоги t_lead :

 df %>%
  mutate(t_lead = lead(time)-time) %>%
  filter(clean_velocity == 0) %>%
  summarize(sum_time = sum(t_lead))

  sum_time
1     4.16
 

Комментарии:

1. Первая часть кода работает » cleanwheeltibble %>% мутировать(t_lead = время(время)-время)», Но когда я делаю все это, это вывод # A tibble: 1 x 1 sum_time <dbl> 1 NA

2. Добавить na.rm=T внутри функции sum? Другой вариант-добавить %>%na.omit()%>% перед summarizie

3. Это кажется неправильным. Он не возвращает фрейм данных с 6 столбцами, в котором позиция 10,6 равна 2,12, что и было запрошено в комментарии под вопросом.

4. Что я сделал, так это поместил первые две строки df %>% mutate(t_lead = lead(time)-time) в новый фрейм данных, в df2 <- df %>% mutate(t_lead = lead(time)-time) котором выводится новая таблица с 6 столбцами