Я работал над кодом для добавления новых столбцов в существующий tbl_df
. Добавьте количество столбцов для значений в столбцах; order_type, food_type, ice_cream_type и customer_info с некоторыми подробностями. Я изложил особенности, которые я ищу в каждом столбце ниже.
То, как я это вижу, есть два варианта: dplyr::if_else
или комбинация dplyr::count
и tidyr::pivot_wider
.
Одним из возможных решений, о котором я подумал, было использование mutate_at
и передача имен отдельных столбцов с помощью if_else
, но я не уверен, что это будет лучшим способом сделать это.
Мое решение ниже использует tidyr
и dplyr
. Код выглядит так, как будто он менее эффективен, чем должен быть. Я думаю, что есть лучшее решение, чтобы делать то, что я ищу.
Я собираюсь сделать следующее:
- order_type будет учитываться только для «phone», а имя столбца будет принимать значение «phone» с «_order» после этого. Теоретически я смотрю, как взять значение из строки и добавить суффикс. Может быть
glue
или paste0
? - Все значения для
food_type
, но переименовать «мороженое» в ice_cream
для имени столбца - Подсчитать все в ice_cream_type, но создать только столбцы подсчета для значений не-NA
- Подсчитывать только те строки, которые имеют «первый раз» или начинаются с «повтор» в пределах
customer_info
столбец - Присоединиться к оригиналу
df
library(tidyverse)
df <- tibble::tribble(
~date, ~Initials, ~order_type, ~food_type, ~ice_cream_type, ~customer_info, ~cost,
"2/1/2020", "JS", "phone", "ice cream", "vanilla", "repeat_multiple", 5,
"1/15/2019", "JO", "online", "entree", NA, "first_time", 20,
"12/29/2017", "JE", "in-person", "snack", NA, "no info", 6.5,
"1/1/2018", "OI", "online", "snack", NA, "repeat_first", 2,
"2/1/2020", "VM", "phone", "entree", NA, "no info", 12,
"1/15/2019", "PJ", "phone", "drink", NA, "repeat_multiple", 3,
"12/29/2017", "JO", "online", "entree", NA, "repeat_first", 14,
"1/1/2018", "EE", "in-person", "ice cream", "chocolate", "first_time", 6,
"2/1/2020", "SL", "online", "entree", NA, "first_time", 6
)
# order_type
order_type_df <- df %>%
group_by(Initials) %>%
count(order_type) %>%
ungroup %>%
pivot_wider(names_from = order_type,
values_from = n,
values_fill = list(n = 0)) %>%
select(Initials, phone_order = phone)
food_type_df <- df %>%
group_by(Initials) %>%
count(food_type) %>%
ungroup %>%
pivot_wider(names_from = food_type,
values_from = n,
values_fill = list(n = 0)) %>%
rename(ice_cream = "ice cream")
ice_cream_df <- df %>%
group_by(Initials) %>%
count(ice_cream_type) %>%
ungroup %>%
pivot_wider(names_from = ice_cream_type,
values_from = n,
values_fill = list(n = 0)) %>%
select(-"NA")
customer_info_df <- df %>%
group_by(Initials) %>%
count(customer_info) %>%
ungroup %>%
pivot_wider(names_from = customer_info,
values_from = n,
values_fill = list(n = 0)) %>%
mutate(repeat_customer = repeat_first + repeat_multiple) %>%
select(Initials, first_time, repeat_customer)
desired_df <- df %>%
left_join (order_type_df) %>%
left_join(food_type_df) %>%
left_join(customer_info_df) %>%
left_join(ice_cream_df)
#> Joining, by = "Initials"Joining, by = "Initials"Joining, by = "Initials"Joining,
#> by = "Initials"
desired_df
#> # A tibble: 9 x 16
#> date Initials order_type food_type ice_cream_type customer_info cost
#> <chr> <chr> <chr> <chr> <chr> <chr> <dbl>
#> 1 2/1/~ JS phone ice cream vanilla repeat_multi~ 5
#> 2 1/15~ JO online entree <NA> first_time 20
#> 3 12/2~ JE in-person snack <NA> no info 6.5
#> 4 1/1/~ OI online snack <NA> repeat_first 2
#> 5 2/1/~ VM phone entree <NA> no info 12
#> 6 1/15~ PJ phone drink <NA> repeat_multi~ 3
#> 7 12/2~ JO online entree <NA> repeat_first 14
#> 8 1/1/~ EE in-person ice cream chocolate first_time 6
#> 9 2/1/~ SL online entree <NA> first_time 6
#> # ... with 9 more variables: phone_order <int>, ice_cream <int>, snack <int>,
#> # entree <int>, drink <int>, first_time <int>, repeat_customer <int>,
#> # chocolate <int>, vanilla <int>