Добавление новых имен столбцов для использования в spread () - PullRequest
0 голосов
/ 28 ноября 2018

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

Этот код: я пытаюсь выбрать три верхние передачи для каждого маршрута(используя slice(1:3), потому что мне нужно не более трех значений. top_n() допускает связи).Затем я пытаюсь spread() создать 6 столбцов: имя и pct для каждого.

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

Фрейм данных:

# A tibble: 7 x 3
route_shortname transfer_to   pct
<chr>           <chr>       <dbl>
1 A               D           0.5  
2 A               E           0.5  
3 B               F           0.667
4 B               G           0.333
5 C               D           0.111
6 C               E           0.111
7 C               G           0.111

Желаемый результат:

# A tibble: 3 x 7
route_shortname transfer1 transfer1_pct transfer2 transfer2_pct transfer3 transfer3_pct
<chr>           <chr>             <dbl> <chr>             <dbl> <chr>             <dbl>
1 A               D                 0.5   E                 0.5   NA               NA    
2 B               F                 0.667 G                 0.333 NA               NA    
3 C               D                 0.111 E                 0.111 G                 0.111

Представляет:

library(tidyverse)

sample_data <- tibble::tribble(
  ~route_shortname, ~transfer_to,              ~pct,
  "A",                "D",               0.5,
  "A",                "E",               0.5,
  "B",                "F", 0.666666666666667,
  "B",                "G", 0.333333333333333,
  "C",                "D", 0.111111111111111,
  "C",                "E", 0.111111111111111,
  "C",                "G", 0.111111111111111
)

transfer_to_table <- sample_data %>%
  group_by(route_shortname) %>%
  mutate(key = c("transfer1", "transfer2", "transfer3"))

#> Error in mutate_impl(.data, dots): Column `key` must be length 2 (the group size) or one, not 3

Ответы [ 2 ]

0 голосов
/ 28 ноября 2018

Несмотря на то, что вы пометили этот вопрос пакетами tidyverse, здесь есть вариант, использующий dcast из data.table, который позволяет вам изменить форму в одну (по общему признанию длинную) строку.

library(data.table)
setDT(sample_data)
dcast(sample_data, route_shortname ~ rowid(route_shortname), value.var = c('transfer_to', 'pct'))
#   route_shortname transfer_to_1 transfer_to_2 transfer_to_3     pct_1     pct_2     pct_3
#1:               A             D             E          <NA> 0.5000000 0.5000000        NA
#2:               B             F             G          <NA> 0.6666667 0.3333333        NA
#3:               C             D             E             G 0.1111111 0.1111111 0.1111111

Вы также можете использовать reshape из base R

sample_data <- as.data.frame(sample_data) # does not work with tibbles for some reason
sample_data$idx <- with(sample_data,
                        ave(route_shortname, route_shortname, FUN = seq_along))
reshape(sample_data, idvar = "route_shortname", timevar = "idx", direction = "wide", sep = "_")
#  route_shortname transfer_to_1     pct_1 transfer_to_2     pct_2 transfer_to_3     pct_3
#1               A             D 0.5000000             E 0.5000000          <NA>        NA
#3               B             F 0.6666667             G 0.3333333          <NA>        NA
#5               C             D 0.1111111             E 0.1111111             G 0.1111111

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

0 голосов
/ 28 ноября 2018
df = read.table(text = "
route_shortname transfer_to   pct
1 A               D           0.5  
2 A               E           0.5  
3 B               F           0.667
4 B               G           0.333
5 C               D           0.111
6 C               E           0.111
7 C               G           0.111
", header=T)

library(tidyverse)

df %>%
  group_by(route_shortname) %>%
  mutate(id = paste0("transfer", row_number())) %>%
  ungroup() %>%
  unite(v, transfer_to, pct) %>%
  spread(id, v) %>%
  separate(transfer1, c("transfer1","transfer1_pct"), sep = "_", convert = T) %>%
  separate(transfer2, c("transfer2","transfer2_pct"), sep = "_", convert = T) %>%
  separate(transfer3, c("transfer3","transfer3_pct"), sep = "_", convert = T)

#   route_shortname transfer1 transfer1_pct transfer2 transfer2_pct transfer3 transfer3_pct
#   <fct>           <chr>             <dbl> <chr>             <dbl> <chr>             <dbl>
# 1 A               D                 0.5   E                 0.5   NA               NA    
# 2 B               F                 0.667 G                 0.333 NA               NA    
# 3 C               D                 0.111 E                 0.111 G                 0.111
...