Вот решение с использованием tidyverse
: я добавил комментарии к шагам, чтобы сделать его более читаемым.
df<- unlist(metadata) %>%
data.frame() %>% # unlist and changing to data.frame
rownames_to_column() %>% #adding row names to data
magrittr::set_colnames(c("Var","value")) %>% #renaming columns
tidyr::separate('Var', paste("Tag", 1:5, sep="_"), sep="[.]", extra="drop") %>% #spliting column to get all levels
dplyr::mutate(Level1= ifelse(grepl("attribute",Tag_2)|grepl("attribute",Tag_3), "attribute",paste0(Tag_2,"_",Tag_3)),
Level1= gsub("\\d.*", "", Level1),
Level2=paste0(Level1,"_",Tag_5),
Level2= gsub("_NA*", "", Level2)
) %>% #cleaning of data based on patterns to reach clean levels
ungroup()%>%
dplyr::group_by(Tag_1,Level2) %>%
dplyr::mutate(n= row_number()) %>%
dplyr::ungroup() %>%
dplyr::mutate(Level2=paste0(Level2,n),
Level3= ifelse(Level1=="attribute",Level1,Level2),
Level4= ifelse(is.na(Tag_5),Level1,Tag_5),
Level4= gsub("level_to_disard_","",Level4),
Level1= gsub("level_to_disard_","",Level1),
Level5= ifelse(Level1=="attribute",Level2,Level1)
) %>% #cleaning again based on patterns to reach clean levels
dplyr::select(Tag_1,Level1,Level2,Level3,Level4,Level5,value) %>%
dplyr::group_by(Tag_1,Level5) %>% # at this step you can change Level number to get data at any other level
dplyr::mutate(value_1=paste0(value,collapse = ",")) %>%
dplyr::select(Tag_1,Level5,value_1) %>%
dplyr::distinct() %>%
tidyr::pivot_wider(names_from =c(Level5),values_from = value_1) # changing to wide format
output:
df
# A tibble: 2 x 6
# Groups: Tag_1 [2]
Tag_1 attribute1 attribute2 columns tags irrelevant
<chr> <chr> <chr> <chr> <chr> <chr>
1 table1 tb1_att1 tb1_att2 tb1_col1_name,tb1_col1_type,tb1_col2_name,tb1_col2_type tag1,tag2,tag3 blabla,blibli
2 table2 tb2_att1 NA tb2_col1_name,bloblo,tb2_col2_name,tb2_col2_type tag1,tag3 NA
Вы можете удалить столбцы, которые не требуются с использованием select
.