#sql #r #hierarchy #cloudera #impala
#sql #r #иерархия #cloudera #impala
Вопрос:
У меня есть сглаженная иерархия глубиной около 10 слоев. Есть ключ, но, к сожалению, этот ключ не был соблюден, поэтому не может быть использован для моей цели.
Мне нужно взять эту плоскую таблицу и превратить ее в широкую иерархию, единственная связь, которая у меня есть, — это идентификатор строки и родительский идентификатор.
Мои данные выглядят так (упрощенно);
id name description code sub_level_name parent_id
1 Parent Company My Big Company MBC Company
2 Franchise1 My Franchise1 MF1 Franchise 1
3 Store1 My Store1 MS1 Store 2
4 Store2 My Store2 MS2 Store 2
5 Store1Owner My Store1Owner MSO1 Store Owner 3
6 Store2Owner My Store2Owner MSO2 Store Owner 4
И я бы хотел, чтобы результат выглядел как;
company_name company_description company_code franchise_name franchise_description franchise_code store_name store_description store_code storeowner_name storeowner_description storeowner_code
Parent Company My Big Company MBC Franchise1 My Franchise1 MF1 Store1 My Store1 MS1 Store1Owner My Store1Owner MSO1
Parent Company My Big Company MBC Franchise1 My Franchise1 MF1 Store2 My Store2 MS2 Store2Owner My Store2Owner MSO2
Обычно я бы использовал pivot_wider и использовал столбец sub_level_name, но это то, о чем я говорил, не соблюдалось в большей области (эта таблица содержит ~ 7000 строк и может иметь глубину 10)
Я чувствую, что мне нужно сделать, это сопоставить родительский идентификатор с идентификатором и объединить столбцы на основе их sub_level_name для создания типов столбцов «x.name , x.description, x.code) и выполнять это строка за строкой, пока не достигнет верхнего уровня иерархии.
Большое спасибо за любую помощь в этом — не обязательно решение R, и решение SQL также было бы отличным.
Редактировать: Dput исходные данные
structure(list(id = c(1, 2, 3, 4, 5, 6), name = c("Parent Company",
"Franchise1", "Store1", "Store2", "Store1Owner", "Store2Owner"
), description = c("My Big Company", "My Franchise1", "My Store1",
"My Store2", "My Store1Owner", "My Store2Owner"), code = c("MBC",
"MF1", "MS1", "MS2", "MSO1", "MSO2"), sub_level_name = c("Company",
"Franchise", "Store", "Store", "Store Owner", "Store Owner"),
parent_id = c(NA, 1, 2, 2, 3, 4)), class = c("spec_tbl_df",
"tbl_df", "tbl", "data.frame"), row.names = c(NA, -6L), spec = structure(list(
cols = list(id = structure(list(), class = c("collector_double",
"collector")), name = structure(list(), class = c("collector_character",
"collector")), description = structure(list(), class = c("collector_character",
"collector")), code = structure(list(), class = c("collector_character",
"collector")), sub_level_name = structure(list(), class = c("collector_character",
"collector")), parent_id = structure(list(), class = c("collector_double",
"collector"))), default = structure(list(), class = c("collector_guess",
"collector")), skip = 1), class = "col_spec"))
Комментарии:
1. не могли бы вы опубликовать воспроизводимый образец ваших данных, пожалуйста (например, с
dput()
)?2. @the_darkside спасибо за этот пример. Надеюсь, правка, которую я внес, поможет.
Ответ №1:
Вы можете попробовать создать id
столбец для каждого sub_level_name
, удалить ненужные столбцы и получить данные в широком формате.
library(dplyr)
df %>%
group_by(sub_level_name) %>%
mutate(id = row_number()) %>%
select(-parent_id) %>%
tidyr::pivot_wider(names_from = sub_level_name,
values_from = c(name, description, code))
Комментарии:
1. Привет, Ронак — к сожалению, я не могу. Ключом, на который я ссылался в верхней части моего поста, по сути, был столбец sub_level_name . Я не могу ее очистить, мне нужно полагаться на отношение родительского идентификатора к идентификатору для построения иерархии. Ваше решение было тем, что я надеялся сделать с самого начала, но из-за различий в иерархии я не могу.
2. @LukeWilliams Можете ли вы добавить еще несколько строк своих данных и показать точный ожидаемый результат на основе этого, чтобы было легче понять, что вы пытаетесь сделать.