Как создавать значения на основе информации о запуске-остановке в отдельном столбце

#r #dataframe #dplyr #tidyr

#r #фрейм данных #dplyr #tidyr

Вопрос:

У меня очень беспорядочный набор данных, созданный исследовательским устройством. Эти данные показывают физиологическую меру («Физио») за каждые несколько миллисекунд («Время»). В выходных данных перечислены несколько пользовательских сообщений, например, когда запускается пробная версия («START_TRIAL n»), когда заканчивается пробная версия («STOP_TRIAL») и другие случайные вещи, которые могут представлять интерес для исследователя. Несколько раз сообщение «START_TRIAL n» повторяется последовательно, а иногда, когда сообщения нет, в ячейке, которая в противном случае была бы пустой, остается простое «0».

Я надеюсь создать новый столбец, который будет указывать, к какому судебному разбирательству относится текущее дело. (См. Пример данных ниже).

Есть ли способ сделать это с помощью dplyr и mutate? Мне интересно, может ли мне понадобиться выполнить оператор if-then, который изменяет значения нового столбца для каждого случая, но, несомненно, есть более элегантное решение? (Заранее благодарю вас за помощь этому новичку!)

 Time    Physio  Cond
1   34  START_TRIAL 1
2   33  0
3   25  RANDOM_MSG
4   43  STOP_TRIAL
5   27  START_TRIAL 2
6   54  START_TRIAL 2
7   32  0
8   54  RANDOM_MSG
9   23  STOP_TRIAL

structure(list(Time = 1:9, Physio = c(34L, 33L, 25L, 43L, 27L, 
54L, 32L, 54L, 23L), Cond = structure(c(4L, 2L, 3L, 6L, 5L, 5L, 
2L, 3L, 6L), .Label = c("", "0", "RANDOM_MSG", "START_TRIAL 1", 
"START_TRIAL 2", "STOP_TRIAL"), class = "factor")), .Names = c("Time", 
"Physio", "Cond"), row.names = c(NA, 9L), class = "data.frame")

  

в

 Time    Physio  Trial   Cond
1   34  1   START_TRIAL 1
2   33  1   0
3   25  1   RANDOM_MSG
4   43  1   STOP_TRIAL
5   27  2   START_TRIAL 2
6   54  2   START_TRIAL 2
7   32  2   0
8   54  2   RANDOM_MSG
9   23  2   STOP_TRIAL

structure(list(Time = 1:9, Physio = c(34L, 33L, 25L, 43L, 27L, 
54L, 32L, 54L, 23L), Trial = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 
2L), Cond = structure(c(4L, 2L, 3L, 6L, 5L, 5L, 2L, 3L, 6L), .Label = c("", 
"0", "RANDOM_MSG", "START_TRIAL 1", "START_TRIAL 2", "STOP_TRIAL"
), class = "factor")), .Names = c("Time", "Physio", "Trial", 
"Cond"), row.names = c(NA, 9L), class = "data.frame")
  

Ответ №1:

Одним из вариантов было бы идентифицировать ‘START_TRIAL’ с помощью grep , выполните match , чтобы получить индекс и fill элементы NA с предыдущим элементом, не являющимся смежным с NA

 library(dplyr)
library(tidyr)
df1 %>% 
   mutate(Trial = match(PhysioCond, unique(grep("START_TRIAL", 
             PhysioCond, value = TRUE)))) %>% 
   fill(Trial)
#    Time    PhysioCond Trial
#1   34 START_TRIAL 1     1
#2   33             0     1
#3   25    RANDOM_MSG     1
#4   43    STOP_TRIAL     1
#5   27 START_TRIAL 2     2
#6   54 START_TRIAL 2     2
#7   32             0     2
#8   54    RANDOM_MSG     2
#9   23    STOP_TRIAL     2
  

ПРИМЕЧАНИЕ: Неясно с именем столбца, но логика должна работать хорошо

данные

 df1 <- structure(list(Time = c(34L, 33L, 25L, 43L, 27L, 54L, 32L, 54L, 
 23L), PhysioCond = c("START_TRIAL 1", "0", "RANDOM_MSG", "STOP_TRIAL", 
"START_TRIAL 2", "START_TRIAL 2", "0", "RANDOM_MSG", "STOP_TRIAL"
 )), class = "data.frame", row.names = c("1", "2", "3", "4", "5", 
  "6", "7", "8", "9"))
  

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

1. @akrun Мне понравился ваш ответ здесь, потому что вы потрясаете своими ответами!!! большое спасибо