У меня есть набор данных, содержащий результаты опроса. Давайте представим, что опрос был разослан тысячам сотрудников, принадлежащих к разным компаниям, я обработал результаты этих опросов, обнаружил некоторые ошибки в этих опросах и теперь хочу отправить настраиваемую сводку ошибок каждому сотруднику, чтобы они может исправить эти ошибки.

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

Например.


Уважаемый (Имя),

Мы выявили всего (количество ошибок) ошибок в опросах, представленных (company_name). Пожалуйста, найдите их ниже:

(error_1_description)

(error_1_survey_IDs)

(error_2_description)

(error_2_survey_IDs)

(error_3_description)

(error_3_survey_IDs)

(error_4_description)

(error_4_survey_IDs)


При отправке получатель видит сводку, относящуюся к его компании, например :

Дорогой Стив,

В опросах, представленных Amazon, мы выявили в общей сложности 20 ошибок. Пожалуйста, найдите их ниже:

Рассматриваемая ошибка 1. Идентификаторы затронутых опросов:

00100A, 00100B, 00100C

Ошибка в вопросе 2. Идентификаторы затронутых опросов:

00100A, 00100B

Ошибка в вопросе 3. Идентификаторы затронутых опросов:

00100A

Ошибка в вопросе 4. Идентификаторы затронутых опросов:

00100B, 00100C


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

Таблицу, содержащую сводку ошибок, можно воссоздать, используя приведенный ниже код:

error_summary <- structure(list(organisation = c("Amazon", "Amazon", "Amazon", 
"Amazon", "Amazon", "Amazon", "Amazon", "Amazon", "Amazon", "Google", 
"Google", "Google", "Google", "Google", "Google", "Google", "Google", 
"Google", "Google", "Google", "Google", "Google", "Google", "Facebook", 
"Facebook", "Facebook", "Facebook", "Facebook", "Facebook", "Facebook", 
"Facebook", "Facebook", "Facebook", "Facebook", "Facebook", "Facebook"
), questionnaire_id = c("00100A", "00100A", "00100A", "00100B", 
"00100C", "00100C", "00100C", "00100D", "00100D", "00100E", "00100E", 
"00100E", "00100F", "00100G", "00100G", "00100G", "00100H", "00100H", 
"00100H", "00100H", "00100H", "00100J", "00100J", "00100K", "00100K", 
"00100K", "00100K", "00100L", "00100L", "00100L", "00100L", "00100M", 
"00100M", "00100M", "00100M", "00100M"), error_message = c("error found in question 1", 
"error found in question 2", "error found in question 4", "error found in question 1", 
"error found in question 2", "error found in question 5", "error found in question 6", 
"error found in question 1", "error found in question 2", "error found in question 1", 
"error found in question 2", "error found in question 4", "error found in question 1", 
"error found in question 2", "error found in question 5", "error found in question 6", 
"error found in question 1", "error found in question 2", "error found in question 3", 
"error found in question 4", "error found in question 5", "error found in question 5", 
"error found in question 6", "error found in question 1", "error found in question 2", 
"error found in question 4", "error found in question 5", "error found in question 2", 
"error found in question 5", "error found in question 6", "error found in question 7", 
"error found in question 2", "error found in question 3", "error found in question 4", 
"error found in question 5", "error found in question 6")), class = c("spec_tbl_df", 
"tbl_df", "tbl", "data.frame"), row.names = c(NA, -36L), spec = structure(list(
    cols = list(organisation = structure(list(), class = c("collector_character", 
    "collector")), questionnaire_id = structure(list(), class = c("collector_character", 
    "collector")), error_message = structure(list(), class = c("collector_character", 
    "collector"))), default = structure(list(), class = c("collector_guess", 
    "collector")), skip = 1), class = "col_spec"))

Эта таблица содержит несколько строк для каждой компании и только три столбца.

Для шаблона данные необходимо реструктурировать так, чтобы они содержали только одну строку для каждой компании, а каждую ошибку и список идентификаторов опросов, содержащие эту ошибку, в отдельных столбцах.

Например, в идеале приведенное выше будет выглядеть так, как показано ниже, где каждый столбец соответствует настраиваемому полю, которое может быть указано в тексте шаблона:

end_goal_template <- structure(list(organisation = c("Amazon", "Google", "Facebook"
), error_1 = c("error found in question 1", "error found in question 1", 
"error found in question 1"), error_1_survey_IDs = c("00100A 00100B 00100D", 
NA, "00100K"), error_2 = c("error found in question 2", "error found in question 2", 
"error found in question 2"), error_2_survey_IDs = c("00100A 00100C 00100D", 
NA, "00100K 00100L 00100M"), error_3 = c("error found in question 3", 
"error found in question 3", "error found in question 3"), error_3_survey_IDs = c(NA, 
NA, "00100M"), error_4 = c("error found in question 4", "error found in question 4", 
"error found in question 4"), error_4_survey_IDs = c("00100A", 
NA, "00100K 00100M"), error_5 = c("error found in question 5", 
"error found in question 5", "error found in question 5"), error_5_survey_IDs = c("00100C", 
NA, "00100K 00100L 00100M"), error_6 = c("error found in question 6", 
"error found in question 6", "error found in question 6"), error_6_survey_IDs = c("00100C", 
NA, "00100L 00100M"), error_7 = c("error found in question 7", 
"error found in question 7", "error found in question 7"), error_7_survey_IDs = c(NA, 
NA, "00100L")), class = c("spec_tbl_df", "tbl_df", "tbl", "data.frame"
), row.names = c(NA, -3L), spec = structure(list(cols = list(
    organisation = structure(list(), class = c("collector_character", 
    "collector")), error_1 = structure(list(), class = c("collector_character", 
    "collector")), error_1_survey_IDs = structure(list(), class = c("collector_character", 
    "collector")), error_2 = structure(list(), class = c("collector_character", 
    "collector")), error_2_survey_IDs = structure(list(), class = c("collector_character", 
    "collector")), error_3 = structure(list(), class = c("collector_character", 
    "collector")), error_3_survey_IDs = structure(list(), class = c("collector_character", 
    "collector")), error_4 = structure(list(), class = c("collector_character", 
    "collector")), error_4_survey_IDs = structure(list(), class = c("collector_character", 
    "collector")), error_5 = structure(list(), class = c("collector_character", 
    "collector")), error_5_survey_IDs = structure(list(), class = c("collector_character", 
    "collector")), error_6 = structure(list(), class = c("collector_character", 
    "collector")), error_6_survey_IDs = structure(list(), class = c("collector_character", 
    "collector")), error_7 = structure(list(), class = c("collector_character", 
    "collector")), error_7_survey_IDs = structure(list(), class = c("collector_character", 
    "collector"))), default = structure(list(), class = c("collector_guess", 
"collector")), skip = 1), class = "col_spec"))

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

Я боролся с этим весь день, в основном используя функции tidyr, такие как pivot_wider, но я чувствую, что это выходит за рамки моих текущих возможностей. Буду безмерно благодарен за любые подсказки или идеи, пожалуйста, и спасибо!

0
Biased_Observer 8 Июн 2021 в 18:32

2 ответа

Лучший ответ

Вот решение pivot_wider. Столбцы не в том же порядке, что и ваш шаблон (и не имеют одинаковых имен), но это должно помочь вам на 90%.

library(tidyverse)
error_summary %>%
  group_by(organisation, error_message) %>%
  summarise(survey_IDs = paste(questionnaire_id, collapse = " ")) %>%
  ungroup() %>%
  mutate(error = gsub(" found in question ", "_", error_message)) %>%
  rename(message = error_message) %>%
  group_by(organisation) %>%
  pivot_wider(id_cols = "organisation", names_from = error,
              values_from = c(message, survey_IDs),
              names_glue = "{error}_{.value}")
2
A. S. K. 8 Июн 2021 в 16:10

Вот решение data.table:

library(data.table)
end_goal <- dcast(data.table(error_summary), organisation ~ error_message, 
    value.var="questionnaire_id", fun.aggregate = paste, collapse=", ", fill=NA)
setnames(end_goal, 
    sub("(error found in question )(.*)", "error_\\2_survey_IDs", colnames(end_goal)))
cn <- colnames(end_goal)[-1]
end_goal[,(sub("_survey_IDs", "", cn)):=data.table(t(cn))]
setcolorder(end_goal,  c("organisation", 
    as.vector(t(matrix(colnames(end_goal)[-1], ncol=2)[, 2:1]))))[]
0
user12728748 8 Июн 2021 в 18:53