Я читаю небольшие текстовые файлы из многих папок в список. Следовательно, у меня есть список длины n с 2 data.frames
.
Вот пример элемента 3 списка (dput в конце вопроса)
ip_list[[3]]
$`dc:a6:32:2d:b6:c4`
# A tibble: 2 x 1
X1
<chr>
1 MAC address is: dc:a6:32:2d:b6:c4
2 IP is: 18.21.162.74
$`dc:a6:32:2d:b6:c4_running`
# A tibble: 1 x 1
datetime
<dttm>
1 2020-03-13 19:11:07
Моя цель преобразовать список в фрейм данных с n машинами и 3 столбцами (ma c, ip, datetime). Я сделал это, как мне кажется, несколько громоздким способом:
n_machines <- length(ip_list)
# first element will be the mac and ip
df <- lapply(1:n_machines,
function (xx) as.data.frame(t(ip_list[[xx]][[1]]),
stringsAsFactors = FALSE)) %>%
bind_rows() %>%
# now clean
rename(mac = V1, ip = V2) %>%
mutate(mac = str_remove(mac, "MAC address is: "),
ip = str_remove(ip, "IP is: "))
# second element will be running time
running_time <- lapply(1:n_machines,
function (xx) as.data.frame(t(ip_list[[xx]][[2]]),
stringsAsFactors = FALSE)) %>%
bind_rows() %>%
rename(datetime = V1)
# join stuff (order should be kept)
df <- bind_cols(df, running_time)
, который дает ожидаемый результат:
df
mac ip datetime
1 dc:a6:32:21:59:2b 18.21.129.94
2 dc:a6:32:2d:8c:ca 18.21.171.210
3 dc:a6:32:2d:b6:c4 18.21.162.74 2020-03-13 19:11:07
4 dc:a6:32:2d:b8:62 18.21.178.96
Вопрос: Есть ли лучший путь? Я чувствую, что должен быть способ сделать это. В частности:
- Использование порядка элементов может скрыть проблему (гораздо лучше иметь способ слияния по адресу ma c, чем полагаться на порядок 1: n)
- Вся эта приятная штука делает свою работу, но у меня возникает ощущение, что ее трудно отладить (и она обязательно взорвется, если
n_machines = 0
) - Использование
as.data.frame(t(...))
громоздко, и я теряю имена (которые я должен переназначить позже), но я не мог найти путь к pivot_wider
или подобному.
Вот небольшой вывод
dput(ip_list[1:4])
list(list(`dc:a6:32:21:59:2b` = structure(list(X1 = c("MAC address is: dc:a6:32:21:59:2b",
"IP is: 18.21.129.94")), class = c("spec_tbl_df", "tbl_df", "tbl",
"data.frame"), row.names = c(NA, -2L), spec = structure(list(
cols = list(X1 = structure(list(), class = c("collector_character",
"collector"))), default = structure(list(), class = c("collector_guess",
"collector")), skip = 0), class = "col_spec")), `dc:a6:32:21:59:2b_running` = structure(list(
datetime = ""), class = "data.frame", row.names = c(NA, -1L
))), list(`dc:a6:32:2d:8c:ca` = structure(list(X1 = c("MAC address is: dc:a6:32:2d:8c:ca",
"IP is: 18.21.171.210")), class = c("spec_tbl_df", "tbl_df",
"tbl", "data.frame"), row.names = c(NA, -2L), spec = structure(list(
cols = list(X1 = structure(list(), class = c("collector_character",
"collector"))), default = structure(list(), class = c("collector_guess",
"collector")), skip = 0), class = "col_spec")), `dc:a6:32:2d:8c:ca_running` = structure(list(
datetime = ""), class = "data.frame", row.names = c(NA, -1L
))), list(`dc:a6:32:2d:b6:c4` = structure(list(X1 = c("MAC address is: dc:a6:32:2d:b6:c4",
"IP is: 18.21.162.74")), class = c("spec_tbl_df", "tbl_df", "tbl",
"data.frame"), row.names = c(NA, -2L), spec = structure(list(
cols = list(X1 = structure(list(), class = c("collector_character",
"collector"))), default = structure(list(), class = c("collector_guess",
"collector")), skip = 0), class = "col_spec")), `dc:a6:32:2d:b6:c4_running` = structure(list(
datetime = structure(1584126667.65542, class = c("POSIXct",
"POSIXt"), tzone = "UTC")), class = c("spec_tbl_df", "tbl_df",
"tbl", "data.frame"), row.names = c(NA, -1L), spec = structure(list(
cols = list(datetime = structure(list(format = ""), class = c("collector_datetime",
"collector"))), default = structure(list(), class = c("collector_guess",
"collector")), skip = 0), class = "col_spec"))), list(`dc:a6:32:2d:b8:62` = structure(list(
X1 = c("MAC address is: dc:a6:32:2d:b8:62", "IP is: 18.21.178.96"
)), class = c("spec_tbl_df", "tbl_df", "tbl", "data.frame"
), row.names = c(NA, -2L), spec = structure(list(cols = list(
X1 = structure(list(), class = c("collector_character", "collector"
))), default = structure(list(), class = c("collector_guess",
"collector")), skip = 0), class = "col_spec")), `dc:a6:32:2d:b8:62_running` = structure(list(
datetime = ""), class = "data.frame", row.names = c(NA, -1L
))))
Обновление
Это была проблема dplyr
, которая была решена, когда я перешел на версию для разработчиков (в настоящее время 0.8.99.9002 ).
Оба ответа дают ожидаемые результаты, и я думаю, что это общие улучшения. Я думаю, что принятый ответ легче читается, но это очень субъективно. Единственное, что меня беспокоит, так это то, что мой предыдущий вариант lapply
был бы достаточно стабильным, в то время как purrr
/ dplyr
довольно часто каннибализировали.