приведение в порядок нескольких столбцов с помощью dplyr - PullRequest
0 голосов
/ 07 октября 2018

Я знаю, что data.table может приводить в порядок несколько столбцов одновременно, в отличие от dplyr, который использует несколько шагов gather и spread, которые трудно визуализировать.

Вот запутанная проблема дляthe tidyverse:

library(tidyverse)
df <- data_frame(month_1 = c("Jan", "Feb", "Mar", "Jun"),
                        score_1 = c(4, 5, 6, 4),
                        month_2 = c("Jan", "Mar", NA, NA),
                        score_2 = c(3, 2, NA, NA),
                        month_3 = c("Feb", "Mar", "Jun", NA),
                        score_3 = c(8, 7, 4, NA))

# A tibble: 4 x 6
  month_1 score_1 month_2 score_2 month_3 score_3
  <chr>     <dbl> <chr>     <dbl> <chr>     <dbl>
1 Jan           4 Jan           3 Feb           8
2 Feb           5 Mar           2 Mar           7
3 Mar           6 NA           NA Jun           4
4 Jun           4 NA           NA NA           NA

Мой желаемый результат будет следующим:

id month score
1  Jan   4
1  Feb   5
1  Mar   6
1  Jun   4
2  Jan   3
2  Mar   2
3  Feb   8  
3  Mar   7
3  Jun   4

data.table пользователи могут решить эту проблему путем плавления с помощью шаблонов, например:

melt(setDT(df), measure = patterns("^month", "^score"))

Но поскольку нет эквивалентной функции dplyr, я понимаю, что потребуется несколько spread.Похоже, что мое решение ниже должно работать, но второе spread не работает:

df %>% 
  gather(key, value) %>% 
  mutate(id = parse_number(key),
         key = str_replace(key, "_[0-9]", "")) %>% 
  spread(key, value )

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

1 Ответ

0 голосов
/ 07 октября 2018

Вы можете обрабатывать столбцы month и score по отдельности, а затем соединять их с помощью purrr::map_dfc:

map_dfc(c("month", "score"), 
        ~ df %>%
          select_at(vars(matches(.x))) %>%
          gather(key, !!.x) %>%
          separate(key, c("col", "id"), sep="_")) %>% 
  filter(complete.cases(.)) %>%
  select(id, month, score)

# A tibble: 9 x 3
 id   month score 
<chr> <chr> <chr>
1 1     Jan   4    
2 1     Feb   5    
3 1     Mar   6    
4 1     Jun   4    
5 2     Jan   3    
6 2     Mar   2    
7 3     Feb   8    
8 3     Mar   7    
9 3     Jun   4    

Объяснение:

  • map_dfc выполняет итерации построковые значения «месяц» и «счет», ссылающиеся на текущее значение как .x.Суффикс dfc выполняет cbind для повторных выходных данных.
  • select_at выбирает только столбцы, которые начинаются с .x
  • gather, изменяет ширину на длинную и именует столбец values строковым значением .x.
  • separate разбивает key на два столбца, содержащих тип столбца (который соответствует значению .x) и число id.
  • После завершения сопоставления и привязки столбцов мы filter отбрасываем пропущенные значения и select наших целевых столбцов.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...