Проблематика
Для того чтобы управлять командой сотрудников необходимы чёткие KPI показатели, которые будут служить точным ориентиром в оценке эффективности их работы. Если в продажах все просто (лиды, сделки, конверсия, ROI и пр. показатели), то в процессной работе программистов, маркетологов, аналитиков, дизайнеров так четко измерить эффективность будет сложно т.к.:
Если в вашей команде более 1 человека - встаёт проблема, связанная со сложностью того, чтобы собрать в кучу всю информацию, в рамках оцениваемой продуктивности сотрудников.
Их результаты работы часто трудно оцифровать, а если и выбраны kpi то обработка данных, их учёт и ежедневный контроль может отнимать огромное количество рабочих часов.
Как решить первую задачу, не покупая лицензии agile платформ, я рассказал в своей предыдущей статье, а вот о том, как это все считать и наглядно визуализировать для оценки в общей рабочей среде мы поговорим ниже.
Решение задачи
В своей работе мы будем использовать таскменеджер Trello и пакет trelloR на языке программирования R. Почему именно такой "стек" можно ознакомиться тут>>
Перед тем как начать оценивать продуктивность выберем для себя основные kpi. Я буду оценивать продуктивность команды аналитиков и ключевыми показателями будут служить:
Объем решаемых задач за период
Скорость решения задач
Число задач закрытых в день постановки
Число закрытия "сложных" задач за период
*Это индивидуально мои метрики, которые важны в моей работе. Оценивать продуктивность, описываемым в этой статье методом, можно в любом разрезе, который только может прийти вам в голову и исходя из индивидуально вашего бизнес-процесса.
И так, сначала устанавливаем среду разработки и ключевые пакеты необходимые для работы. Для решения вышеописанной задачи нам потребуется установить пакеты для:
работы с API Trello — «trelloR»
работы со временем и временными периодами — «lubridate»
работы с таблицами и агрегации данных — «dplyr»
работы с визуализацией — «ggplot2»
сбор нескольких визуализаций в одну — «ggpubr»
Чтобы установить пакеты из основного репозитория CRAN примените базовую функцию install.packages, а для загрузки пакетов с github функцию install_github:
remotes::install_github("jchrom/trelloR") install.packages("lubridate", dependencies = TRUE) install.packages("dplyr ", dependencies = TRUE) remotes::install_github("jchrom/trelloR") install.packages("ggplot2", dependencies = TRUE) install.packages("ggpubr ", dependencies = TRUE)
Для отправки запросов к API Trello нам потребуется токен, как его получить можно прочесть тут>>*
Еще одним важным шагом перед визуализацией является стандартизация всех досок сотрудников в рамках ваших бизнес-процессов. В своей работы мы внедрили:
Единый набор меток для каждой из задач в Trello, разделив их по "срочности-важности" и по направлениям деятельности в рамках задачи

Метки в карточках Trello
Обязательное заполнение даты начала и даты окончания выполнения каждой из задач

Настройка даты в карточке Trello
Перенос всех выполненных задач в столбцы с единым форматом и указания месяца выполнения задачи

К сожалению, без предварительной стандартизации всех досок выполнить дальнейший анализ будет невозможно
Получаем данные для визуализации
# Подключаем все необходимые пакеты для работы library(trelloR) library(lubridate) library(dplyr) library(ggplot2) library(ggpubr) # Указываем путь к папке где лежит полученный ранее token setwd("C:\\*********\\R_script\\trello") # Собираем в список доски сотрудников, которых мы будем анализировать board_id <- c("https://trello.com/b/wNV1HMse/максим-м", "https://trello.com/b/tXrO68ix/максим-я", "https://trello.com/b/fCZrgJYg/арсений", "https://trello.com/b/HeLC3RVE/анатолий", "https://trello.com/b/xweaki49/софия") # Собираем циклом статистику со всех досок в общую таблицу stattrello <- data.frame() # будущая сводная таблица for (xi in 1:length(board_id)) { cardList <- get_board_lists(board_id[xi], query = list(customFieldItems = "true")) cardList$zadach <- NA # число задач за каждый период for (i in 1:length(cardList$id)) { cardList$zadach[i] <- nrow(get_list_cards(cardList$id[i])) } cardList$spec <- stringr::str_to_title(basename(board_id[xi])) cardList <- cardList %>% select(id, spec, name, zadach) stattrello <- bind_rows(stattrello,cardList) }

Собираем списки карточек всех сотрудников и сводим их в единую таблицу для получения ID столбцов по периодам и числа выполненных задач за данные периоды:
# Фильтруем сводные данные только по задачам за последние 3 месяца. # (эффективность по основным kpi будет оцениваться в разрезе этого периода) lid <- stattrello %>% filter(grepl("20",stattrello$name)==T) lid$name <- parse_date_time(lid$name, "my") lidvse <- lid lid <- lid %>% filter(name > floor_date(today() - months(3), "month")) # Используя ID списков с карточками собираем задачи по каждому списку allvcard <- data.frame() # Все задачи всех сотрудников type_zadach <- data.frame() # Типы задач по направлениям #Запускаем цикл для сбора for (i in 1:nrow(lid)) { cards_v <- get_list_cards(lid$id[i]) cards_v$spec <- lid$spec[i] cards_v$datezad <- lid$name[i] if(length(bind_rows(cards_v$labels))!=0){ tmp <- bind_rows(cards_v$labels) %>% group_by(name) %>% summarise(ЧислоЗадач = n()) tmp$spec <- max(cards_v$spec) tmp$datezad <- max(cards_v$datezad) type_zadach <- bind_rows(type_zadach,tmp) cards_v <- tidyr :: unnest_longer(cards_v,labels) cards_v <- rename(cards_v$labels, Naprav=3) %>% select(Naprav) %>% bind_cols(cards_v) %>% select(id, due, Naprav,spec) # В поле ID зашифрована дата создания карточки. Проводим расшифровку для всех задач cardID <- cards_v$id[i] dateList <- data.frame(dateadd = NA) dateList[1,1] <- strtoi(strtrim(cardID, 8), 16L) dateList$dateadd <- as.POSIXct(dateList$dateadd, origin = "1970-01-01") dateList <- data.frame(dateadd = NA) for (i in 1:length(cards_v$id)) { cardID <- cards_v$id[i] dateList[i,1] <- strtoi(strtrim(cardID, 8), 16L) } dateList$dateadd <- as.POSIXct(dateList$dateadd, origin = "1970-01-01") cards_v["dateadd"] <- dateList$dateadd # Вычисляем время от создания задачи до плановой даты её завершения cards_v <- cards_v %>% bind_cols() %>% data.frame( raznica = trunc(as.numeric(as.POSIXct(cards_v$due) - cards_v$dateadd)/24)) %>% select(-due) allvcard <- bind_rows(allvcard,cards_v) }else{print("no") }}
После выполнения всех предварительных манипуляций с данными, мы можем приступить к оформлению
Визуализация
Выводим цифры в среду визуализации используя пакет ggplot2 и строим графики по каждому из показателей:
# Задаем единый стандарт отображения данных (стиль графиков) tema <- theme(legend.position="right",axis.text=element_text(size=7), axis.title=element_text(size=10,face="bold"), legend.text=element_text(size=10), legend.title = element_text(size=9), plot.title = element_text(size=10), plot.margin = margin(5, 20, 5.5, 5)) # Строим график по общему числу решенных задач за период # Переводим даты в стандартный вид из того что были в списках Trello stattrello$id <- as.character(as.Date(floor_date(as.POSIXct(strtoi(strtrim(stattrello$id, 8), 16L), origin = "1970-01-01"),"month"))+1) # Подготавливаем столбцы к отображению на графике stattrello <- stattrello %>% rename(date=id) %>% group_by(spec,date) %>% summarise(zadach = sum(zadach)) # Строим график grafik_vse <- ggplot(data=stattrello, aes(x=as.character(date), y=zadach)) + scale_fill_discrete(name = "Сотрудники" ) + geom_bar(aes(fill=spec), position = position_dodge(), stat="identity") + geom_text(aes(label=zadach, y = zadach +1, group = spec), position = position_dodge(0.9), size=2.5) + theme(legend.position="bottom",axis.text=element_text(size=7), axis.title=element_text(size=10,face="bold"), legend.text=element_text(size=10), legend.title = element_text(size=9), plot.title = element_text(size=10), plot.margin = margin(10, 50, 20, 10)) + labs(title = "Закрыто задач в прошлом периоде", x = "Дата", y = "Задач, шт.")
В результате получаем график по числу выполненных задач на каждого из сотрудников

Получаем графики и таблицы для остальных интересующих нас показателей:
# Формируем график по задачам для направлений деятельности type_zad <- type_zadach %>% filter(grepl("ВАЖНО|Пауза", name)!=T) %>% mutate(date = format(datezad, "%m-%Y")) %>% group_by(spec,name) %>% summarise(nwork= sum(ЧислоЗадач)) typ_p <- ggplot(data=type_zad, aes(x=name, y=nwork, group=spec)) + scale_fill_discrete(name = "Сотрудники" ) + geom_bar(aes(fill=spec), position = position_dodge(), stat="identity") + geom_text(aes(label=nwork, y = nwork+1, group = spec), position = position_dodge(0.9), size=2.5) + tema + labs(title = "Задачи по направлениям за 3 мес.", x = "Дата", y = "Задач, шт.")
График по "фокусу" в направлениях деятельности для каждого из сотрудников

*Получение графиков и таблиц остальных kpi показателей происходит аналогично выше описанному методу визуализации данных. Дабы не мучать вас кодом, ограничимся на этих примерах=)
После того как мы собрали нужные нам графики их необходимо соединить в один файл - дашборд:
# Объединение визуализации ggarrange(grafik_vse, ggarrange(typ_p, p1, ncol = 2, nrow = 1, heights = c(1, 1),common.legend = T,legend = "bottom"), nrow = 2,legend = "right") # Сохраняем полученный файл для загрузки в Trello ggsave("sotrudniki.png", width =25, height = 20, units = "cm", device="png")
Итог сведения графиков:

Теперь визуализацию передаем в 1-ый список на нашем общем дашборде, который мы создавали в прошлой статье.
#Сначала удаляем старые визуалы если они там были bid = get_id_board("o****W") # 1ый лист в доске куда пишем наши графики lid <- get_board_lists(bid)$id[1] cid <- get_list_cards(lid) # Удаление delete_resource(resource = "card", id = cid$id[1]) delete_resource(resource = "card", id = cid$id[2]) # Создаем новые карточки в которые после добавим графики payload = list( idList = lid, name = "Показатели работы", pos = "bottom" ) create_resource("card", body = payload) payload = list( idList = lid, name = "Сводка", pos = "bottom" ) create_resource("card", body = payload) # Снова обращаемся к этому листу с уже новыми но пока пустыми карточками bid = get_id_board("o****W") lid <- get_board_lists(bid)$id[1] cid <- get_list_cards(lid) # Добавляем наши сводные графики add_card_attachment(cid$id[1], file = "sotrudniki.png", cover = TRUE) add_card_attachment(cid$id[2], file = "zadachi.png", cover = TRUE)

По итогу на общей доске появились сводные графики по тем KPI которые важны для ежедневного контроля. При нажатии на изображения в Trello можно сразу раскрыть превью и оперативно оценить как идут дела в рамках необходимых показателей:

Далее настраиваем автоматический запуск скрипта для актуализации дашборда и задаём нужное количество раз обновлений в день.
Итог
Полученные данные, карточки и задачи расположены на одном листе и для оценки эффективности департамента не нужно открывать +100500 разных досок. Такой подход экономит кучу времени и делает контроль за исполнением задач оперативным, а работу с сотрудниками эффективнее.
При желании, можно анализировать и делать выводы о том, кто с какой эффективностью решает задачи с детализацией до каждого сотрудника, создавая им свои мини отчеты.
Используя оценочные коэффициенты по каждому из KPI, можно формировать стандарты работы, в рамках любого периода, наблюдать динамику и принимать решение о дополнительном премировании или депремирование сотрудников на основе близких к объективным* данных.
*Для повышения точности оценки сотрудников, перед построением автоматизации необходимо как следует продумать критерии "сложных" задач, чтобы присвоение и закрытие таких карточек контролировалось руководителем и не происходила чрезмерная "переоценка" важности-сложности работ.
Но это уже совсем другая история =)
П.С.: Буду признателен комментариям и конструктивной критике кода.
