#r #tidyr
Вопрос:
У меня возникли трудности с поворотом парных столбцов. Я понимаю, что есть names_pattern
аргумент, и я не могу понять, как заставить это работать.
Мои данные выглядят так:
structure(list(Q8_1_avg = 4.72562264837839, Q8_1_avg_se = 0.0595342202500642,
Q8_1_unweighted = 4.90473815461347, Q8_2_avg = 4.65508494735021,
Q8_2_avg_se = 0.0541589332376175, Q8_2_unweighted = 4.6498753117207,
Q8_3_avg = 5.4756060523178, Q8_3_avg_se = 0.0534895224170486,
Q8_3_unweighted = 5.57506234413965), row.names = c(NA, -1L
), class = "data.frame")->dat
И мой желаемый результат выглядит так:
df<-data.frame(
Question=c('Q8_1', 'Q8_2','Q8_3'),
#Values taken from Q8_[123]_avg
Weighted_Average=c(4.72,4.65, 5.47),
#Values taken from Q8_[123]_avg_se
Weighted_SE=c(0.05,0.05 ,0.05),
#Values taken from Q8_[123]_unweighted
Unweighted_Average=c(4.90, 4.64, 5.57)
)
df
Спасибо вам за любую помощь.
Ответ №1:
Мы можем использовать pivot_longer
. При необходимости используйте rename
для изменения имен столбцов. Укажите в names_to
качестве вектора «Вопрос» (который возвращает префиксную часть имени столбца) и .value
возвращает значение в длинном формате. Затем, в names_pattern
, захватите префиксную часть, т. Е. один или несколько символов, не являющихся _
( [^_]
), за которыми следуют _
и некоторые цифры ( \d
) в виде группы ( (...)
), затем _
и вторая группа захвата, включающая остальные символы ( (.*)
)
library(dplyr)
library(tidyr)
dat %>%
pivot_longer(cols = everything(), names_to = c("Question",
".value"), names_pattern = "^([^_] _\d )_(.*)")
# A tibble: 3 × 4
Question avg avg_se unweighted
<chr> <dbl> <dbl> <dbl>
1 Q8_1 4.73 0.0595 4.90
2 Q8_2 4.66 0.0542 4.65
3 Q8_3 5.48 0.0535 5.58
Комментарии:
1. Ладно, это потрясающе. Не могли бы вы объяснить мне логику, пожалуйста? В частности, регулярное выражение!
2. @spindoctor Поскольку регулярное выражение всегда меня заводит, я подумал, что скажу, что в последнее время я использую интерактивное регулярное выражение, и это сделало мое регулярное выражение для устранения неполадок намного более упрощенным. Используя то, что я придумал
names_pattern = "(\w\d_\d)_(.*)"
(чтобы получить буквы, цифры и » » в определенном шаблоне до разрыва » «) иnames_pattern = "(.*_.)_(.*)"
. Они работают в вашем примере, но могут быть слишком ограниченными, если ваши настоящие имена более изменчивы.