Часть1.Rmd
29 октября 2022 г., 22:08
За последние полгода Хогвартс сильно опустел. Вместо шумных и весёлых разговоров по коридорам разлеталось лишь эхо чьих-то редких шагов. Учащиеся, преподаватели и даже администрация были вынуждены покинуть страну на неопределённый срок. Гриффиндорцев нашего класса оставалось лишь трое. Предметы были сильно урезаны из-за нехватки профессоров. Тем не менее, мы с моей однокурсницей прилежно посещали занятия. Что нам ещё оставалось?
Сзади послушались семенящие догоняющие звуки
– А правда, что твой дядя научил тебя парсингу?
Я собрался было ответить, но замер от изумления. Посреди пролёта стояла деканка нашего факультета. Её длинные светлые волосы были распущены и закрывали плечи. Со спины я не сразу заметил, что её палочка была на изготовке.
– Сдавайтесь, Екатерина. Я вовсе не желаю вам вреда, – раздалось из конца коридора. Я подошёл чуть ближе, и...
– В класс, коллеги, – проговорила ЕМШ, не сводя глаз с незнакомца, – я разберусь.
– Но мы хотим помочь вам! – моя сокурсница выпалила эту фразу так резко, что на её щеках выступили слёзы. Вероятно, она знала что-то, чего я не знал.
– Мы не оставим вас в опасности, – подтвердил я, и вдруг заметил, что с датасетом нашей деканки что-то не так... Он как будто распался на множество разных баз данных, беспомощно летающих вокруг неё.
– Екатерина, осторожно, он загрязняет данные! Какая подлость! Сразу видно, что вы работаете на Тёмного Лорда.
– Замолчи, щенок. – Коротко ответил незнакомец. Его изуродованное лицо казалось мне таким часто мелькающим... А может?
– ЕМШ, используйте против него dplyr::group_by(), это соберёт датасеты в один и вы сможете собрать данные воедино!
– Не получится, – оборвал я, – в датасетах разное количество колонок. Они не скомпилируются. Он всё предусмотрел. Но где же я мог видеть его?
Внезапно лицо Екатерины Михайловны прояснилось. Она подняла палочку в воздух и набрала:
```{r}```
fname_list <- list_files(path="C:/Путь к датасетам", full.names = TRUE)
N = 0
District <-c()
Results <- c()
Competitive <- c()
Candidates <- c()
Region <-c()
getmode <- function(v) {
uniqv <- unique(v)
uniqv[which.max(tabulate(match(v, uniqv)))]
}
for(fname in fname_list){
OIK <- read_tsv(fname)
A <- sum(OIK$col1)+sum(OIK$col12)
v = getmode(OIK$reg)
Region <- c(Region, v)
OIK <- OIK[,-c(1:17)]
OIK <- OIK[, -length(OIK)]
Vek <- OIK %>% colSums() %>% sort(decreasing = TRUE)
N = N+1
District <- c(District, N)
v = length(OIK)
Candidates <- c(Candidates, v)
v = (Vek[1] - Vek[2])/A
Competitive <- c(Competitive, v)
v = Vek[1]/A
Results <- c(Results, v)
}
ALLOIK <- data.frame(District, Results, Competitive, Candidates)
ALLOIK <- data.frame(Results, Competitive, Candidates, row.names(ALLOIK), Region, row.names = District)
```
Незнакомец пошатнулся и едва не упал, схватившись за колено.
– Уходите, Северус. В Хогвартсе Вам не рады.
– Я уйду. Но вернусь я с такими людьми, о встрече с которыми вы пожалеете. Все вы.
После все мы сидели в комнате нашего факультета.
– Екатерина Михайловна, я понимаю, что у вас не было времени оставлять в коде комментарии, но можете всё же ещё раз показать, что вы сделали? Вполне вероятно, что мы столкнёмся с необходимостью составлять общий датасет из разных неструктурированных файлов. Как вы это сделали?
– Ответ увидите в новом заклинании под названием "никак"! Ну, а если серьёзно, давайте попробуем разобраться. Базы данных были почти идентичны друг другу, но содержали разное количество колонок, именно это вызвало сложности. Однако если мы можем вытащить количество колонок, то процесс автоматизируется, и вы сможете не проделывать одну и ту же процедуру сотни раз, а сделать цикл. Эмм... На этом моменте хочется нравоучительно сказать "Запомните, дети, циклы в R делать себе дороже", как говорил один классик "это не способ, другим не советую, но выходов у меня нет". Но давайте всё же разберём по частям мною наколдованное:
#Здесь я создаю список из все-всех датасетов, их может быть хоть бесчисленное множество, главное, чтобы нужные нам колонки назывались одинаково.
fname_list <- list_files(path="C:/Путь", full.names = TRUE)
#Теперь создаём векторы для нужных нам данных (мне были нужны доли победивших кандидатов, разница между первым и вторым кандидатами, количество кандидатов в округе)
N = 0
District <-c()
Results <- c()
Competitive <- c()
Candidates <- c()
Region <-c()
#Эту функцию подсчёта моды я честно позаимствовала у своего коллеги А. В. Кынева. Как вы знаете, в Хогвартсе он уже не преподаёт...
getmode <- function(v) {
uniqv <- unique(v)
uniqv[which.max(tabulate(match(v, uniqv)))]
}
###Наконец, создаём цикл:
for(fname in fname_list){
OIK <- read_tsv(fname)
#"A" я считаю для подсчёта долей голосов, это совершенно опционально!
A <- sum(OIK$`col1`)+sum(OIK$`col2`)
#считываем самый частый регион, добавляем в вектор
v = getmode(OIK$reg)
Region <- c(Region, v)
#Убираем ненужные мне колонки
OIK <- OIK[,-c(1:17)]
OIK <- OIK[, -length(OIK)]
#Суммируем все строки для итогового подсчёта голосов и ранжируем их по убыванию
Vek <- OIK %>% colSums() %>% sort(decreasing = TRUE)
N = N+1
District <- c(District, N)
#считаем количество кандидатов в округе, добавляем в вектор
v = length(OIK)
Candidates <- c(Candidates, v)
#считаем разницу голосов в округе между первыми двумя кандидатами, добавляем в вектор
v = (Vek[1] - Vek[2])/A
Competitive <- c(Competitive, v)
#считаем долю голосов в округе победившего кандидата, добавляем в вектор
v = Vek[1]/A
Results <- c(Results, v)
}
#Формируем единый датасет из получившихся векторов по всем базам данных, думаю, это вы умеете!
ALLOIK <- data.frame(District, Results, Competitive, Candidates)
ALLOIK <- data.frame(Results, Competitive, Candidates, row.names(ALLOIK), Region, row.names = District)
– Вот это да! Но некоторые переменные вы могли бы прописать и одной строчкой, – заметил я.
– И это вы мне говорите после всего того, что мы пережили? Отваги вам не занимать! Послушайте, я понимаю ваше стремление довести всё до идеала, но в критические моменты важно, чтобы данные были под рукой. И этот момент был именно таким!
"А мы переходим к нашей следующей рубрике" – горько усмехнулся про себя я.