Цель: Извлечение вложенной (внутри вложенной) информации для создания одного кадра данных.
У меня есть сложный список, содержащий несколько других списков, которые также имеют несколько вложенных списков. Я начал извлекать списки для создания (нескольких) фреймов данных. В какой-то момент я застрял, поскольку хочу извлечь вложенную информацию, сохраняя при этом не вложенную информацию. Вот некоторые поддельные данные, чтобы дать вам представление о структуре:
df <- list(FirstInput = structure(list(ProductID = c("6973e325-242c-4735-85be-f66f4f979a3e",
"bae3884c-7789-4417-9371-55d02e8a1dbd", "5ee23690-8cd8-4a97-a570-6baf7c3b0694",
"e03b971f-12a5-4fda-b89f-5cccbd74b776", "9dd9deff-9300-4764-80ee-027dfcd16cee",
"b6cb6d84-dc64-4d66-8667-7e5031073b02", "dfce29c9-1bad-42d4-a5c4-ee4a45ac7c51",
"fad51a6c-f695-4c35-94c7-edb185ac055c", "9905300b-6cf3-4309-b5d1-d10d71770832",
"e20b69b5-66e8-4be8-b360-4dbc46b696a8"), ProductText = c("a",
"b", "c", "d", "e", "f", "g", "h", "i", "j"), ProductPrice = c(0,
0, 0.4296875, 0.337430167597765, 0.380471380471381, 0.281368821292776,
0.831818181818182, 0.201010101010101, 0.183333333333333, 0.316924778761062
), ProductCharacteristic1 = c(434, 371, 896, 895, 891, 263, 990,
990, 990, 904)), row.names = c(NA, -10L), class = "data.frame"),
SecondInput = structure(list(ProductID = c("6973e325-242c-4735-85be-f66f4f979a3e",
"bae3884c-7789-4417-9371-55d02e8a1dbd", "5ee23690-8cd8-4a97-a570-6baf7c3b0694",
"e03b971f-12a5-4fda-b89f-5cccbd74b776", "9dd9deff-9300-4764-80ee-027dfcd16cee",
"b6cb6d84-dc64-4d66-8667-7e5031073b02", "dfce29c9-1bad-42d4-a5c4-ee4a45ac7c51",
"fad51a6c-f695-4c35-94c7-edb185ac055c", "9905300b-6cf3-4309-b5d1-d10d71770832",
"e20b69b5-66e8-4be8-b360-4dbc46b696a8"), ProductText = c("a",
"b", "c", "d", "e", "f", "g", "h", "i", "j"), ProductPrice = c(0,
0, 0.4296875, 0.337430167597765, 0.380471380471381, 0.281368821292776,
0.831818181818182, 0.201010101010101, 0.183333333333333,
0.316924778761062), ProductCharacteristic1 = c(434, 371,
896, 895, 891, 263, 990, 990, 990, 904), ProductCharacteristic2 = c(FALSE,
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE
), ProductCharacteristic3 = c(TRUE, TRUE, TRUE, TRUE, TRUE,
TRUE, TRUE, TRUE, TRUE, TRUE), ProductCharacteristic4 = c(0,
0, 0, 0, 1, 1, 1, 1, 1, 1), ProductCharacteristic5 = c(0,
0, 0, 0, 0, 0, 1, 1, 1, 1), GroupedCharacteristic1 = structure(list(
Thing1 = c(986, 988, 1070, 1158, 1108, 947, 0, 0, 0,
1083), Thing2 = c(73, 55, 240, 120, 214, 125, 0, 0, 0,
119), Thing3 = c(42, -34, 201, -1, 82, 65, 0, 0, 0, 9
), Thing4 = c(85, 30, 101, 67, 57, 46, 946, 1005, 999,
80), Thing5 = c(152, 71, 433, 169, 322, 247, 5, 0, 0,
168), Thing6 = c(169, 77, 494, 169, 362, 0, 0, 0, 0,
184), Thing7 = c(40, 32, 29, 42, 20, 106, 0, 0, 0, 41
), Thing8 = c(249, 150, 68, 66, 71, 178, 0, 0, 0, 125
), Thing9 = c(36, 12, 109, 72, 114, 5, 0, 0, 0, 96),
Thing10 = c(0, 425, 9, 372, 175, 21, 0, 0, 0, 204)), row.names = c(NA,
-10L), class = "data.frame"), GroupedCharacteristic2 = list(
NULL, NULL, "Something nice", c("Something nice", "somthing really nice",
"but also bad"), "Something", "Something", "Something",
"Something", "Something", c("Something nice", "somthing really nice",
"but also bad", "Great")), GroupedCharacteristic3 = structure(list(
Test1 = list("Blabla", "Blabla", "Bladibla", "Chekcthis",
"Bladibla", "Blablablabla", "Blablablabla", "Blablablabla",
"Bladiblabla", "Bladiblabla"), Test2 = list("Fakedata1",
"Fakedata2", "Fakedata2", "Chekcthis", "Fakedata2",
"Fakedata1", "Fakedata1", "Fakedata2", "Fakedata2",
"Fakedata1")), row.names = c(NA, -10L), class = "data.frame")), row.names = c(NA,
-10L), class = "data.frame"))
Желаемый (окончательный) фрейм данных: - это фрейм данных с каждым продуктом в каждом файле в одной строке (см. ниже).
То, что я пробовал: Первое, что я попробовал, было использовать map в сочетании с extract или extract2 для извлечения всех отдельных компонентов и объединения их вместе, используя округленное число (в каждом файле).
df <- test3 %>%
map(., function(x) x %>% select_if(negate(is.list))) %>%
rbindlist(fill=TRUE, idcol = "ID") %>%
group_by(ID) %>%
mutate(row = as.character(row_number())) %>%
ungroup()
df1 <- test3 %>%
map(., extract2, "GroupedCharacteristic2") %>%
unlist(., recursive = FALSE) %>%
enframe() %>%
mutate(row = gsub("SecondInput", "", name) ,
ID = gsub("[0-9]+$", "", name),
GroupedCharacteristic2 = as.character(value)) %>%
select(-name, -value)
df2 <- test3 %>%
map(., extract2, c("GroupedCharacteristic1")) %>%
rbindlist(fill = TRUE, idcol = "ID")%>%
group_by(ID) %>%
mutate(row = as.character(row_number())) %>%
ungroup()
df_final <- df %>%
left_join(df1, by = c("ID","row")) %>%
left_join(df2, by = c("ID","row"))
Это работает, поскольку иногда определенная информация недоступна, и выдержка может с этим справиться. Тем не менее, это кажется невероятно рискованным, поскольку матч будет неправильным, если что-то случится с рядовым игроком.
Для некоторых других частей я попытался сделать что-то вроде
df1 <- df %>% map(., function(x) x %>% select(-GroupedCharacteristic2, -GroupedCharacteristic3) %>%
flatten() ) %>%
bind_rows(.id = "ID")
Идея состоит в том, чтобы сохранить всю информацию уровня 1 при извлечении и выравнивании GroupedCharacteristic1. Нечто подобное можно сделать в GroupedCharacteristics2 и 3, после чего можно сопоставить перекрывающуюся информацию. Однако это не работает, так как эти сгруппированные признаки не всегда доступны, и выбор дает ошибку.
Так что я ищу быстрое (здесь я показываю только 2 файла, но у меня есть 9k файлов в списке) сочетание извлечения и пользовательской функции. Вероятно, я упускаю что-то очевидное, поэтому любые советы или помощь очень ценятся!
Окончательный фрейм данных выглядит так:
structure(list(ID = c("FirstInput", "FirstInput", "FirstInput",
"FirstInput", "FirstInput", "FirstInput", "FirstInput", "FirstInput",
"FirstInput", "FirstInput", "SecondInput", "SecondInput", "SecondInput",
"SecondInput", "SecondInput", "SecondInput", "SecondInput", "SecondInput",
"SecondInput", "SecondInput"), ProductID = c("6973e325-242c-4735-85be-f66f4f979a3e",
"bae3884c-7789-4417-9371-55d02e8a1dbd", "5ee23690-8cd8-4a97-a570-6baf7c3b0694",
"e03b971f-12a5-4fda-b89f-5cccbd74b776", "9dd9deff-9300-4764-80ee-027dfcd16cee",
"b6cb6d84-dc64-4d66-8667-7e5031073b02", "dfce29c9-1bad-42d4-a5c4-ee4a45ac7c51",
"fad51a6c-f695-4c35-94c7-edb185ac055c", "9905300b-6cf3-4309-b5d1-d10d71770832",
"e20b69b5-66e8-4be8-b360-4dbc46b696a8", "6973e325-242c-4735-85be-f66f4f979a3e",
"bae3884c-7789-4417-9371-55d02e8a1dbd", "5ee23690-8cd8-4a97-a570-6baf7c3b0694",
"e03b971f-12a5-4fda-b89f-5cccbd74b776", "9dd9deff-9300-4764-80ee-027dfcd16cee",
"b6cb6d84-dc64-4d66-8667-7e5031073b02", "dfce29c9-1bad-42d4-a5c4-ee4a45ac7c51",
"fad51a6c-f695-4c35-94c7-edb185ac055c", "9905300b-6cf3-4309-b5d1-d10d71770832",
"e20b69b5-66e8-4be8-b360-4dbc46b696a8"), ProductText = c("a",
"b", "c", "d", "e", "f", "g", "h", "i", "j", "a", "b", "c", "d",
"e", "f", "g", "h", "i", "j"), ProductPrice = c(0, 0, 0.4296875,
0.337430167597765, 0.380471380471381, 0.281368821292776, 0.831818181818182,
0.201010101010101, 0.183333333333333, 0.316924778761062, 0, 0,
0.4296875, 0.337430167597765, 0.380471380471381, 0.281368821292776,
0.831818181818182, 0.201010101010101, 0.183333333333333, 0.316924778761062
), ProductCharacteristic1 = c(434, 371, 896, 895, 891, 263, 990,
990, 990, 904, 434, 371, 896, 895, 891, 263, 990, 990, 990, 904
), ProductCharacteristic2 = c(NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
FALSE, FALSE), ProductCharacteristic3 = c(NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,
TRUE, TRUE, TRUE), ProductCharacteristic4 = c(NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1), ProductCharacteristic5 = c(NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, 0, 0, 0, 0, 0, 0, 1, 1, 1,
1), row = c("1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
"1", "2", "3", "4", "5", "6", "7", "8", "9", "10"), GroupedCharacteristic2 = c(NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, "NULL", "NULL", "Something nice",
"c(\"Something nice\", \"somthing really nice\", \"but also bad\")",
"Something", "Something", "Something", "Something", "Something",
"c(\"Something nice\", \"somthing really nice\", \"but also bad\", \"Great\")"
), Thing1 = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 986, 988,
1070, 1158, 1108, 947, 0, 0, 0, 1083), Thing2 = c(NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA, 73, 55, 240, 120, 214, 125, 0, 0,
0, 119), Thing3 = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 42,
-34, 201, -1, 82, 65, 0, 0, 0, 9), Thing4 = c(NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, 85, 30, 101, 67, 57, 46, 946, 1005, 999,
80), Thing5 = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 152,
71, 433, 169, 322, 247, 5, 0, 0, 168), Thing6 = c(NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA, 169, 77, 494, 169, 362, 0, 0, 0,
0, 184), Thing7 = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 40,
32, 29, 42, 20, 106, 0, 0, 0, 41), Thing8 = c(NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, 249, 150, 68, 66, 71, 178, 0, 0, 0, 125
), Thing9 = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 36, 12,
109, 72, 114, 5, 0, 0, 0, 96), Thing10 = c(NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, 0, 425, 9, 372, 175, 21, 0, 0, 0, 204)), row.names = c(NA,
-20L), class = c("tbl_df", "tbl", "data.frame"))