Удаление набора смежных строк кадра данных, соответствующих заданному шаблону c - R - PullRequest
0 голосов
/ 07 января 2020

Я разместил этот вопрос на 12/19. Я получил один ответ, который был очень полезен, но не совсем то, что я искал. Тогда вопрос был закрыт тремя людьми со спецификацией, это нуждалось в большем внимании. инструкции указали, что я могу обновить вопрос или опубликовать новый, но после редактирования, чтобы сделать его более сфокусированным, он остался закрытым. Итак, я публикую это снова.

Вот ссылка на отредактированный вопрос, включая более краткий набор данных (который был одним критическим комментарием): Определение определенного c шаблона в нескольких смежных строки одного столбца - R

Но в случае, если эта ссылка не разрешена, вот содержимое:

Мне нужно удалить указанный набор c строк из данные, когда они происходят. В нашем опросе, автоматизированном телефонном опросе, инструмент опроса во время этого звонка попытается трижды попросить респондента ввести ответ. После трех тайм-аутов вопроса инструмент опроса зависает. В основном это происходит, когда вызов поступает на чью-то голосовую почту.

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

Шаблон, который я ищу, выглядит как это в столбце Взаимодействия:

enter image description here

Это не должно быть вступлением. Это может быть любая часть опроса, где респондент запрашивает ответ ТРИ раза, но ответ не предоставляется, поэтому вызов не выполняется. Но он должен быть зажат между «Ответить» (телефон поднимает трубку) и «Тайм-аут. Вызов не удался». (ошибка).

Я пытался применить то, что я узнал из вчерашнего решения (о кодировании длины серии), к моему другому вопросу индексации, но я не мог заставить его работать ни в малейшей степени. Итак, вот я.

Вот пример набора данных:

Это 4 респондента и каждое взаимодействие между инструментом опроса и респондентом (или их телефоном, по сути).

Вот код для фрейма данных: Это идет в текстовый редактор Google Drive с кодом

Ответ, который я получил от Руи Баррадаса, был таким:

removeRows <- function(X, col = "Interaction", 
                       ans = "Answer", 
                       fail = c("Timeout. Call failed.", "Partial", "Enqueueing call"))
{  
  a <- grep(ans, X[[col]])
  f <- which(X[[col]] %in% fail)
  a <- a[findInterval(f, a)]

  for(i in seq_along(a)){
    X[[col]][a[i]:f[i]] <- NA_character_
  }
  Y <- X[complete.cases(X), , drop = FALSE]
  Y
}

removeRows(survey_data)

Однако это решение слишком широкое. Мне нужно специально удалить только те строки, в которых делается 3 попытки, чтобы вызвать ответ, но ответ не предоставляется. Таким образом, если приглашение является вводным, а ответа нет, значит, время ожидания истекло, и в конце концов вызов не удался.

Спасибо!

Ответы [ 2 ]

1 голос
/ 07 января 2020

Я бы обычно использовал пакет dplyr. Я уверен, что этот метод может быть изменен, чтобы использовать базу R, если это необходимо, но dplyr имеет готовые функции, чтобы сделать его проще. Комментарии в коде, чтобы объяснить, что он делает.

df2 <- df %>%
  # Find any entry where there were three timeouts evenly spaced afterwards and set TRUE.
  # You can add other conditions here if needed (to check even leading values).
  mutate(triple_timeout = ifelse(
    lead(Interaction,n=1) == "Timeout" & 
      lead(Interaction,n=3) == "Timeout" & 
      lead(Interaction,n=5) == "Timeout",
    TRUE,
    FALSE
  )) %>%
  # Lead will have some NA values so fill those in
  mutate(triple_timeout = ifelse(is.na(triple_timeout),FALSE,triple_timeout)) %>%
  # Every triple timeout has six entries that should be true, but only the first is id'd.
  # Use an `or` logic and lag statements to set value to true for 5 entries after any TRUE
  mutate(triple_timeout = triple_timeout | 
           lag(triple_timeout,n=1) |
           lag(triple_timeout,n=2) |
           lag(triple_timeout,n=3) |
           lag(triple_timeout,n=4) |
           lag(triple_timeout,n=5)
         ) %>%
  # Lag will have some NA values to fill those in
  mutate(triple_timeout = ifelse(is.na(triple_timeout),FALSE,triple_timeout)) %>%
  # Filter out any TRUE triple_filter
  filter(!triple_timeout) %>%
  # Remove the filter column
  select(-triple_timeout)
0 голосов
/ 08 января 2020

Я точно буду знать в следующем месяце, когда у меня будут данные такого рода для 5K респондентов. Но у меня приличная оперативная память. Спасибо еще раз!

...