Как прочитать файл с определенным форматом в R?
Я хотел бы прочитать файл, где каждая строка представляет набор данных, содержащий дату, текст, а также цифры. Пример:
Fri Dec 11 12:40:01 CET 2015 Uptime: 108491 Threads: 2 Questions: 576603 Slow queries: 10 Opens: 2238 Flush tables: 1 Open tables: 7 Queries per second avg: 5.314
Fri Dec 11 12:50:01 CET 2015 Uptime: 109090 Threads: 2 Questions: 580407 Slow queries: 10 Opens: 2253 Flush tables: 1 Open tables: 6 Queries per second avg: 5.320
Fri Dec 11 13:00:01 CET 2015 Uptime: 109690 Threads: 2 Questions: 583895 Slow queries: 10 Opens: 2268 Flush tables: 1 Open tables: 8 Queries per second avg: 5.323
Fri Dec 11 13:10:01 CET 2015 Uptime: 110290 Threads: 1 Questions: 586891 Slow queries: 10 Opens: 2279 Flush tables: 1 Open tables: 6 Queries per second avg: 5.321
Fri Dec 11 13:20:01 CET 2015 Uptime: 110890 Threads: 2 Questions: 590871 Slow queries: 10 Opens: 2292 Flush tables: 1 Open tables: 5 Queries per second avg: 5.328
Здесь нет общего разделяющего символа (как в CSV), но формат можно описать довольно хорошо, так как можно использовать табуляции, символы и текст.
%DATESTRING%\tUptime: %uptime% Threads: %threads% Questions: %questions% Slow queries: %slow% Opens: %opens% Flush tables: %flush% Open tables: %otables% Queries per second avg: %qps%
Есть ли функция, которая берет описание формата и файла и заполняет data.frame заданными данными?
2 ответа
Еще два варианта:
txt <- "Fri Dec 11 12:40:01 CET 2015 Uptime: 108491 Threads: 2 Questions: 576603 Slow queries: 10 Opens: 2238 Flush tables: 1 Open tables: 7 Queries per second avg: 5.314
Fri Dec 11 12:50:01 CET 2015 Uptime: 109090 Threads: 2 Questions: 580407 Slow queries: 10 Opens: 2253 Flush tables: 1 Open tables: 6 Queries per second avg: 5.320
Fri Dec 11 13:00:01 CET 2015 Uptime: 109690 Threads: 2 Questions: 583895 Slow queries: 10 Opens: 2268 Flush tables: 1 Open tables: 8 Queries per second avg: 5.323
Fri Dec 11 13:10:01 CET 2015 Uptime: 110290 Threads: 1 Questions: 586891 Slow queries: 10 Opens: 2279 Flush tables: 1 Open tables: 6 Queries per second avg: 5.321
Fri Dec 11 13:20:01 CET 2015 Uptime: 110890 Threads: 2 Questions: 590871 Slow queries: 10 Opens: 2292 Flush tables: 1 Open tables: 5 Queries per second avg: 5.328"
## first just tack on the date label
txt <- gsub('^', 'Date: ', readLines(textConnection(txt)))
Опция 1
sp <- strsplit(txt, '\\s{2,}')
out <- lapply(sp, function(x) gsub('([\\w ]+:)\\s+(.*)$', '\\2', x, perl = TRUE))
dd <- setNames(do.call('rbind.data.frame', out),
gsub('([\\w ]+):\\s+(.*)$', '\\1', sp[[1]], perl = TRUE))
dd[, -1] <- lapply(dd[, -1], function(x) as.numeric(as.character(x)))
dd
вариант 2: этот использует yaml
пакет, но гораздо более простой и делает преобразование типов для вас
yml <- gsub('\\s{2,}', '\n', txt)
do.call('rbind.data.frame', lapply(yml, yaml::yaml.load))
# Date Uptime Threads Questions Slow queries Opens Flush tables
# 1 Fri Dec 11 12:40:01 CET 2015 108491 2 576603 10 2238 1
# 2 Fri Dec 11 12:50:01 CET 2015 109090 2 580407 10 2253 1
# 3 Fri Dec 11 13:00:01 CET 2015 109690 2 583895 10 2268 1
# 4 Fri Dec 11 13:10:01 CET 2015 110290 1 586891 10 2279 1
# 5 Fri Dec 11 13:20:01 CET 2015 110890 2 590871 10 2292 1
# Open tables Queries per second avg
# 1 7 5.314
# 2 6 5.320
# 3 8 5.323
# 4 6 5.321
# 5 5 5.328
Пакеты tidyr
есть некоторые вспомогательные функции, которые могут быть полезны для этого, хотя я не удивлюсь, если для этой работы будет создано больше специальных инструментов.
Мы начинаем с загрузки данных, в данном случае из строки
raw <- 'Fri Dec 11 12:40:01 CET 2015 Uptime: 108491 Threads: 2 Questions: 576603 Slow queries: 10 Opens: 2238 Flush tables: 1 Open tables: 7 Queries per second avg: 5.314
Fri Dec 11 12:50:01 CET 2015 Uptime: 109090 Threads: 2 Questions: 580407 Slow queries: 10 Opens: 2253 Flush tables: 1 Open tables: 6 Queries per second avg: 5.320
Fri Dec 11 13:00:01 CET 2015 Uptime: 109690 Threads: 2 Questions: 583895 Slow queries: 10 Opens: 2268 Flush tables: 1 Open tables: 8 Queries per second avg: 5.323
Fri Dec 11 13:10:01 CET 2015 Uptime: 110290 Threads: 1 Questions: 586891 Slow queries: 10 Opens: 2279 Flush tables: 1 Open tables: 6 Queries per second avg: 5.321
Fri Dec 11 13:20:01 CET 2015 Uptime: 110890 Threads: 2 Questions: 590871 Slow queries: 10 Opens: 2292 Flush tables: 1 Open tables: 5 Queries per second avg: 5.328'
df <- read.csv(textConnection(raw), header=F)
Здесь я использовал read.csv
так что я получаю его как фрейм данных, но вы также можете просто использовать readLines
и добавить его в рамку самостоятельно.
Затем мы обрабатываем это
library(tidyr)
> processed <- df %>% extract(V1,
c("Date", "Uptime", "Threads", "Questions"),
"(.*) *Uptime: (\\d+) *Threads: (\\d+) *Questions: (\\d+)")
> processed
Date Uptime Threads Questions
1 Fri Dec 11 12:40:01 CET 2015 108491 2 576603
2 Fri Dec 11 12:50:01 CET 2015 109090 2 580407
3 Fri Dec 11 13:00:01 CET 2015 109690 2 583895
4 Fri Dec 11 13:10:01 CET 2015 110290 1 586891
5 Fri Dec 11 13:20:01 CET 2015 110890 2 590871
Должно быть понятно, как извлечь оставшиеся столбцы отсюда.