{
    "version": "https:\/\/jsonfeed.org\/version\/1",
    "title": "Блог об аналитике, визуализации данных, data science и BI, заметки с тегом: tableau",
    "home_page_url": "http:\/\/test.leftjoin.ru\/tags\/tableau\/",
    "feed_url": "http:\/\/test.leftjoin.ru\/tags\/tableau\/json\/",
    "icon": "http:\/\/test.leftjoin.ru\/user\/userpic@2x.jpg",
    "author": {
        "name": "Николай Валиотти",
        "url": "http:\/\/test.leftjoin.ru\/",
        "avatar": "http:\/\/test.leftjoin.ru\/user\/userpic@2x.jpg"
    },
    "items": [
        {
            "id": "148",
            "url": "http:\/\/test.leftjoin.ru\/all\/skvoznoy-identifikator-reshenie-problemy-metchinga-personalnyh-d\/",
            "title": "Сквозной идентификатор: решение проблемы мэтчинга персональных данных студентов Refocus",
            "content_html": "<p><img src=http:\/\/test.leftjoin.ru\/pictures\/cover.png  border=“0” width=100% height=100%><\/p>\n<p>В системах сквозной аналитики ключевую роль играет правильная модель атрибуции. Без нее данные невозможно интерпретировать, и их ценность для бизнеса невелика. При этом важно понимать, что любая модель напрямую зависит от качества данных.<\/p>\n<p>Частая проблема с сырыми данными в том, что информация об одном клиенте дублируется или, напротив, противоречит друг другу в разных источниках.<\/p>\n<p>Кроме того, что предобработка данных — база для аналитика, без правильного объединения персональных данных в принципе сложно отследить клиентский путь. Значит, нужно настраивать процессы объединения неоднородных персональных данных.<\/p>\n<p>Сегодня в любом клиентском бизнесе воронки регистрации устроены таким образом, что клиенты попадают в базу множеством способов — часто через маркетинговые каналы, которых всегда много (рассылки, реклама, соцсети). В каждом таком канале может быть ссылка на форму подписки, регистрацию на платформе или чат, и один клиент часто проходит все эти этапы. Сразу же образуется путаница в идентификации, которая сильно влияет на качество данных и результаты аналитики, если ее не лечить.<\/p>\n<p>Мы столкнулись с этой проблемой, работая с одним из наших клиентов, и решили ее, создав сквозной идентификатор. Это уникальный номер, который присваивается реальному клиенту и дублируется во все источники, где есть данные об этом клиенте, тем самым избавляя от путаницы.<\/p>\n<h2>Кейс Refocus: данные и путь клиента<\/h2>\n<p>Мы разрабатывали кастомную систему сквозной аналитики для эдтех-стартапа Refocus. Данные каждого студента в системы Refocus попадали из нескольких источников и были записаны несколько раз — как минимум при регистрации на курс, при первом входе на образовательную платформу и при входе в чат сопровождения.<\/p>\n<p>В нашем случае мэтчинг был важнее всего по трем источникам из тринадцати:<\/p>\n<ul>\n<li><b>amoCRM,<\/b> где фиксируется весь клиентский путь студента;<\/li>\n<li><b>Discord,<\/b> где проходило сопровождение студентов;<\/li>\n<li><b>Thinkific,<\/b> сама образовательная платформа с курсами.<\/li>\n<\/ul>\n<p>Остальные источники, с которыми мы работали, либо не содержали данных студентов (например, цифры эффективности работы sales-менеджеров были завязаны на данных сотрудников и трекались через другие системы), либо дублировали информацию из указанных трех.<\/p>\n<p>В Discord и Thinkific данные попадали напрямую, от студентов при регистрации в системах, а затем подтягивались в amoCRM. Основные причины несовпадения клиентских данных как у Refocus, так и в похожих случаях — человеческий фактор (опечатки), наличие у людей более чем одного телефона или адреса почты и ограничения самих платформ, с которых приходят данные: разный заданный формат полей и их количество.<\/p>\n<p>Часть этих факторов может решаться корректировкой самой клиентской воронки. Правда, не все платформы позволяют одинаково настроить вводные поля, а просьбы вводить данные в конкретном формате не всегда работают и не страхуют от ошибок. Плюс, задача аналитиков — получить чистые данные в любом случае.<\/p>\n<h2>Задача и поиск решения<\/h2>\n<p>Данные в Refocus мы подгружали в хранилище в BigQuery напрямую из интересующих нас источников (рекламных кабинетов, LMS и т. д.), используя Python. В дальнейшем на этих данных строились дашборды в Tableau.<\/p>\n<p>Обнаружить проблему несложно — при создании хранилища и дальнейшей выгрузке данных из него мы в любом случае чистим датасет от дубликатов и несовпадений.<\/p>\n<p>Поля, в которых возникали ошибки и для которых нам важен был мэтчинг, чтобы правильно отследить клиентский путь:<\/p>\n<ul>\n<li>имя — да, люди иногда вводят разные вариации ФИО (Юлия, Юля и Бля — на деле один человек!);<\/li>\n<li>телефон — с кодом страны или без, с пробелами, дефисами или слитно;<\/li>\n<li>электронная почта — длинные строки сложного формата, в которых легко опечататься.<\/li>\n<\/ul>\n<p>Поначалу, пока количество студентов Refocus было относительно небольшим, достаточно было скриптов, которые объединяли данные по одному из этих полей. В полученных таблицах в Tableau проводился поиск строк с пустым значением в соответствующем поле — и вот видно всех студентов, чьи данные не сошлись.<\/p>\n<p>Количество таких строк было в пределах пары десятков, и трекать и объединять их было несложно вручную. Это делалось прямо в первоисточниках сотрудниками Refocus, которые могли поправить опечатки и ошибки у себя в системах. После этого наш код выгрузки в хранилище перезапускался и тянул уже чистые данные. Если после этого что-то не сходилось, то наши аналитики правили информацию на уровне базы данных.<\/p>\n<p>Но при росте компании в какой-то момент число студентов, потерянных при мэтчинге, могло достигать сотни за месяц. Пока ошибка обнаружится, данные поправят в источниках, а мы перезапустим код выгрузки, могло пройти несколько часов — а это критичный интервал. Да и перезапускать выгрузку каждый день ради нескольких несовпадений — неэффективно. Стало понятно, что масштаб проблемы требует более точного и универсального решения.<\/p>\n<p>Вообще, в такой ситуации возможны несколько вариантов. Можно бесконечно править скрипты мэтчинга, учитывая новые и новые случаи и создавая костыли. А можно, например, настроить алерты в оркестраторе процессов (в нашем случае  — Airflow), которые позволят моментально узнавать о появившемся несовпадении и объединять “потерянные” клиентские сущности по паре за раз. Но это все еще неполная автоматизация, и она только ускоряет, а не упрощает процесс.<\/p>\n<p>Руководствуясь соображениями эффективности, мы предложили ввести сквозной идентификатор — одно значение ID, присваиваемое одному клиенту после автоматической интеграции его данных из разных источников.<\/p>\n<h2>Реализация решения и рабочий процесс<\/h2>\n<p>Чтобы понять масштаб проблемы, мы начали с того, что создали таблицы несовпадающих персональных данных. Для этого мы использовали скрипты на Python. Эти скрипты объединяли данные из разных источников и создавали из них большую сводную таблицу. Для того, чтобы свести данные о студенте в одну сущность, использовался мэтчинг по адресу электронной почты. Мы попробовали мэтчить по имени, фамилии, телефону (который сначала надо было привести к одному формату!) и почте, и именно последний вариант показал самую высокую точность. Возможно, дело в том, что из всех данных почта имеет самый однородный формат, поэтому остается учитывать только опечатки.<\/p>\n<p>Например, нам нужно было мэтчить данные для создания дашборда по возвратам, о которых информация объединялась как раз из наших трех основных источников. В ранней версии скрипта данные отбирались таким образом:<\/p>\n<pre class=\"e2-text-code\"><code>WITH snapshot_ AS (\r\n      SELECT DISTINCT s.*,\r\n        IFNULL(ae.name, ap.name) as contact_name,\r\n        ap.phone, ae.email,\r\n        split(replace(trim(lower(ae.email)),' ',''),'@')[OFFSET(0)] as email_first_part,\r\n        ai.thinkific_id, ai.intercom_id, ac.student_id\r\n      FROM (\r\n        SELECT *,\r\n          ROW_NUMBER() OVER(PARTITION BY lead_id ORDER BY updated_at DESC) as num_,\r\n        FROM `Differture.amocrm_leads_snapshot`\r\n      ) s\r\n      LEFT JOIN (\r\n        SELECT DISTINCT lead_id, contact_id, name, email,\r\n          ROW_NUMBER() OVER(PARTITION BY lead_id ORDER BY contact_id) as num1_\r\n        FROM `Differture.amo_emails`\r\n      ) ae using(lead_id)\r\n      LEFT JOIN (\r\n        SELECT DISTINCT lead_id, contact_id, name, phone,\r\n          ROW_NUMBER() OVER(PARTITION BY lead_id ORDER BY contact_id) as num2_\r\n        FROM `Differture.amo_phones`\r\n      ) ap using(lead_id)\r\n      LEFT JOIN `Differture.amo_contact_thinkific_intercom_match` ai using(lead_id)\r\n      LEFT JOIN `Differture.AmoContacts` ac on cast(ae.contact_id as string)=ac.amo_id\r\n      WHERE (num_=1 or num_ is null) and (num1_=1 or num1_ is null) and (num2_=1 or num2_ is null)\r\n        and s.pipeline_id in (4920421,5245535) and s.status_id=142 and lower(s.lead_name) not like '%test%'\r\n    )<\/code><\/pre><p>Как можно заметить, идея сквозного идентификатора здесь уже присутствует — фигурирует <tt>student_id<\/tt>. На самом деле, в этой версии скрипта это графа из AmoContacts — таблицы, в которой хранятся только данные из amoCRM. Никаких джойнов по <tt>student_id<\/tt> пока не происходит. А происходят по <tt>email_first_part<\/tt>, адресу почты до символа @:<\/p>\n<pre class=\"e2-text-code\"><code>select distinct * from th_amo_ds_rf\r\n    left join calendly ce using(email_first_part)\r\n    left join typeform_live tfl on email_first_part=tf_email_first_part\r\n    left join typeform tf using(email_first_part)\r\n    left join csat using(email_first_part)<\/code><\/pre><p>Первым шагом по практическому введению идентификатора была таблица <b>students_main_info<\/b>, созданная в BigQuery in-house специалистом Refocus. К сожалению, у нас нет доступа к коду, который использовался для присвоения идентификатора. Зато мы можем показать вид этой таблицы:<\/p>\n<div class=\"e2-text-table\">\n<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n<tr>\n<td style=\"text-align: left\">student_full_name<\/td>\n<td style=\"text-align: center\">string<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left\">student_email<\/td>\n<td style=\"text-align: center\">string<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left\">student_country_id<\/td>\n<td style=\"text-align: center\">string<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left\">student_country_name<\/td>\n<td style=\"text-align: center\">string<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left\">student_courses_ids<\/td>\n<td style=\"text-align: center\">array<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left\">student_courses_names<\/td>\n<td style=\"text-align: center\">array<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left\">student_cohort_id<\/td>\n<td style=\"text-align: center\">string<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left\">student_cohort_name<\/td>\n<td style=\"text-align: center\">string<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left\">cohort_community_manager_name<\/td>\n<td style=\"text-align: center\">string<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left\">cohort_community_manager_email<\/td>\n<td style=\"text-align: center\">string<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left\">student_onboarding_live_session_id<\/td>\n<td style=\"text-align: center\">string<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left\">student_onboarding_live_session_time<\/td>\n<td style=\"text-align: center\">string<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left\">student_onboarding_live_session_zoom_url<\/td>\n<td style=\"text-align: center\">string<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left\">amo_contact_id<\/td>\n<td style=\"text-align: center\">string<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left\">intercom_contact_id<\/td>\n<td style=\"text-align: center\">string<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left\">thinkific_student_id<\/td>\n<td style=\"text-align: center\">string<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left\">discord_user_id<\/td>\n<td style=\"text-align: center\">string<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left\">discord_user_discord_id<\/td>\n<td style=\"text-align: center\">string<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left\">discord_guild_id<\/td>\n<td style=\"text-align: center\">string<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left\">discord_channel_id<\/td>\n<td style=\"text-align: center\">string<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: left\">discord_roles<\/td>\n<td style=\"text-align: center\">string<\/td>\n<\/tr>\n<\/table>\n<\/div>\n<p>В students_main_info хранились данные из нужных источников с общим идентификатором в первой строке, и объединение проходило через сравнение этого поля.<\/p>\n<p>При этом поле <tt>student_id<\/tt> использовалось пока не везде; также использовались другие поля этой таблицы — например, <tt>thinkific_student_id<\/tt> или <tt>discord_user_id<\/tt>.<\/p>\n<p>После выгрузки и мэтчинга данных с помощью students_main_info студентов, которые потерялись при объединении, стало меньше, чем при первой схеме мэтчинга. Так мы убедились, что движемся в верном направлении. Тем не менее, использование одной таблицы, которая содержит больше десятка полей обо всех имеющихся персональных данных, не очень эффективно. Данные в ней уже обработаны скриптом специалиста Refocus, и если надо сверить их с сырыми источниками или ввести новый критерий отслеживания, все придется менять на бэкенде.<\/p>\n<h2>Что получилось в итоге<\/h2>\n<p>После теста сквозного идентификатора через одну большую таблицу мы продолжили улучшать структуру данных на бэке. Вместо students_main_info усилиями специалиста Refocus появилась подробная сеть более мелких таблиц, которые могут обращаться друг к другу и лежат в одном хранилище с нашими таблицами сырых данных.<\/p>\n<p>Вот так выглядела схема соотношения этих таблиц:<\/p>\n<p><img src=http:\/\/test.leftjoin.ru\/pictures\/image-2.png  border=“0” width=100% height=100%><\/p>\n<p>А вот так выглядела основная таблица Students:<\/p>\n<p><img src=http:\/\/test.leftjoin.ru\/pictures\/students.png border=“0” width=40% height=40%><\/p>\n<p>В ней-то и находились основные персональные данные студентов с присвоенным идентификатором, и к ней можно было обращаться для мэтчинга из остальных источников.<\/p>\n<p>Остальные таблицы выглядели похоже: всегда было поле с идентификатором и информация о какой-то характеристике студента — когорта, курс, роль в дискорде и так далее.<\/p>\n<p>Финальный код, написанный нашими аналитиками,  объединял данные при выгрузке из хранилища, и больше не опирался на ненадежный мэтчинг через имейл.<\/p>\n<p>Сначала он отбирал собранные нами данные из amoCRM <tt>(amocrm_leads_snapshot)<\/tt> и объединял их с контактной информацией клиентов. Затем в таблицу добавлялось поле <tt>student_id<\/tt> и отбирались данные, которые понадобятся нам дальше.<\/p>\n<pre class=\"e2-text-code\"><code>WITH snapshot_ AS (\r\n      SELECT DISTINCT s.*,\r\n        ac.name as contact_name, ac.phone, ac.email,\r\n        split(replace(trim(lower(ac.email)),' ',''),'@')[OFFSET(0)] as email_first_part,\r\n        ac.intercom_id, ac.student_id\r\n      FROM (\r\n        SELECT *,\r\n          ROW_NUMBER() OVER(PARTITION BY lead_id ORDER BY updated_at DESC) as num_,\r\n        FROM `Differture.amocrm_leads_snapshot`\r\n      ) s\r\n      LEFT JOIN (\r\n        select cast(al.amo_id as INT64) as lead_id, cast(ac.amo_id as INT64) as contact_id,\r\n          ac.name, emails as email, phone, student_id, ic.intercom_id,\r\n          ROW_NUMBER() OVER(PARTITION BY al.amo_id ORDER BY ac.amo_id) as num1_\r\n        from `Differture.AmoContacts` ac\r\n        left join `Differture.AmoLeads` al on al.amo_contact_id=ac.id\r\n        left join `Differture.IntercomContacts` ic using(student_id)\r\n        , unnest(ac.emails) emails\r\n      ) ac using(lead_id)\r\n      WHERE (num_=1 or num_ is null) and (num1_=1 or num1_ is null)\r\n        and s.pipeline_id in (4920421,5245535) and s.status_id=142 and lower(s.lead_name) not like '%test%'\r\n    )<\/code><\/pre><p>Теперь при создании общей таблицы о возвратах с данными из amo, Thinkific и Discord объединение проходило через student_id:<\/p>\n<pre class=\"e2-text-code\"><code>th_amo_ds_rf as (\r\n      select distinct * except (channel_id, channel),\r\n        ifnull(channel_id, 'Not in discord') as channel_id,\r\n        ifnull(channel, 'Not in discord') as channel\r\n      from thinkific_amo_refunds\r\n      full outer join discord using(student_id)\r\n    )<\/code><\/pre><p>Когда объединенные таблицы данных студентов были созданы, получить таблицы несовпадений можно было простой строкой кода в Tableau:<\/p>\n<p><img src=http:\/\/test.leftjoin.ru\/pictures\/filter.png border=“0” width=50% height=50%><\/p>\n<p>Пустое значение поля student_id означает, что мэтча не случилось — где-то информация расходилась слишком сильно и не подтянулась в таблицы с идентификатором. Раньше, до введения идентификатора, поиск был таким же, но обращался к полям почты, телефона или имени-фамилии.<\/p>\n<p>Ниже можно увидеть таблицу, где данные из Thinkific не совпадали с amoCRM после перехода на Student ID. В этом случае студент есть в LMS, значит, на курсе учится — но его либо нет в системе учета, либо данные в ней разнятся с LMS.<\/p>\n<p><img src=http:\/\/test.leftjoin.ru\/pictures\/unnamed.png  border=“0” width=100% height=100%><\/p>\n<p>А вот таблица, где данные из Discord не совпадали с amoCRM. Все так же, как выше — студент есть в чатах сопровождения, но не ищется по своим данным в amoCRM.<\/p>\n<p><img src=http:\/\/test.leftjoin.ru\/pictures\/discord.png  border=“0” width=100% height=100%><\/p>\n<p>Оба скриншота показывают количество несовпадений примерно за месяц. Как видно по этим таблицам, количество несовпадений уменьшилось с 80-90 до пары десятков — примерно на 75%. Это позволило сократить количество перезапусков кода выгрузки вручную и уменьшить затраты времени и технических ресурсов на поддержание системы.<\/p>\n<h2>Выводы<\/h2>\n<p>Сквозной идентификатор — эффективное решение проблемы мэтчинга персональных данных. Он позволяет максимально автоматизировать процесс отслеживания и устранения несовпадений или дубликатов клиентских сущностей при выгрузке данных для анализа. В случаях, когда объем данных в системе невелик, а у компании нет возможности выделить ресурсы на реализацию такого решения, можно воспользоваться и другими вариантами. Например, алерты в оркестраторе процессов хорошо справятся в ситуации, когда объединить данные — вопрос ручного запуска одного скрипта раз в неделю. Но сквозной идентификатор — наверное, самое универсальное из доступных решений, которое покроет большинство ошибок и заметно уменьшит погрешность в качестве данных.<\/p>\n",
            "date_published": "2024-09-16T17:57:31+03:00",
            "date_modified": "2024-09-16T17:57:05+03:00",
            "image": "http:\/\/test.leftjoin.ru\/pictures\/students.png",
            "_date_published_rfc2822": "Mon, 16 Sep 2024 17:57:31 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "148",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css"
                ],
                "og_images": [
                    "http:\/\/test.leftjoin.ru\/pictures\/students.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/image-2.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/filter.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/unnamed.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/discord.png"
                ]
            }
        },
        {
            "id": "147",
            "url": "http:\/\/test.leftjoin.ru\/all\/kak-pereverstka-pomogaet-prevratit-horoshiy-dashbord-v-otlichny\/",
            "title": "Как переверстка помогает превратить хороший дашборд в отличный",
            "content_html": "<p><img src=http:\/\/test.leftjoin.ru\/pictures\/0oblogka.png  border=“0” width=100% height=100%><\/p>\n<p>В кастомных системах сквозной аналитики конечный продукт, с которым взаимодействует пользователь — дашборды. Он не видит хранилище, витрины данных, скрипты, а дашборды видит каждый день, поэтому важно сделать их не только функциональными, но и понятными. Не всегда удается сразу нащупать оптимальный вариант, и полезно вести работу поэтапно.<\/p>\n<p>Дело в том, что в современных BI-тулах, которые мы используем — в частности, в популярном Tableau — возможности кастомизации гораздо шире, чем может себе представить сотрудник, мигрирующий с excel-таблиц. Часто пользователь просто не знает, каким вообще может быть дашборд и как составить ТЗ.<\/p>\n<p>В итоге дашборд содержит огромное количество данных, но возможность их продуктивно использовать спрятана за фильтрами, визуальной сложностью, долгой загрузкой.<\/p>\n<p>Именно такая ситуация сложилась у нас в процессе работы с образовательным стартапом Refocus.<\/p>\n<p>Один из главных их дашбордов — обзор <b>SLA (Service Level Agreement).<\/b> Его пользователи — руководители отдела продаж и сейлз-менеджеры. Именно здесь их интересует прежде всего скорость обработки входящих лидов в зависимости от ряда факторов, от источника лида до региона.<\/p>\n<p>Нормативное значение этого показателя для Refocus — 15 минут, значит, там, где он выше, есть потенциал для оптимизации процессов и роста выручки.<\/p>\n<p>Мы работаем над дашбордами <b>итеративно:<\/b> интервью с пользователем — прототип — фидбэк — следующая версия — фидбэк, и так далее. Но в случае с SLA после утверждения финальной версии остались нерешенные аналитиками функциональные проблемы.<\/p>\n<p>У заказчика было желание оптимизировать дашборды и бюджет на это, так что мы предложили общую переверстку и подключили к проекту датавиз-эксперта.<\/p>\n<h2>Версия 1: с чем мы работаем<\/h2>\n<p>Первая версия SLA-дашборда, которой некоторое время пользовался клиент, выглядела так:<\/p>\n<p><img src=http:\/\/test.leftjoin.ru\/pictures\/1-32.png  border=“0” width=100% height=100%><\/p>\n<p>В фокусе три графика:<\/p>\n<ol start=\"1\">\n<li>Скаттерплот по <b>времени ответа<\/b> с момента получения лида.<\/li>\n<li>Гистограмма по <b>медианному времени ответа.<\/b><\/li>\n<li>Гистограмма по <b>средней длительности первого звонка<\/b> с лидом.<\/li>\n<\/ol>\n<p>Справа — 15 фильтров, от региона и гранулярности до имени сотрудника, работавшего с лидом.<\/p>\n<p>Сверху — много текста, поясняющего тонкости работы с фильтрами по времени.<\/p>\n<h2>Задача<\/h2>\n<p>Представьте, что ваш технический бэкграунд испарился, и вы на месте пользователя: о чем вам говорят эти графики? Сколько кликов вам нужно совершить, чтобы оценить перформанс подчиненных в вашем отделе? Чтобы сравнить SLA для лидов из разных источников? Ясен ли текст-легенда?<\/p>\n<p>А главное — есть ли у вас понимание, как сделать понятнее и что сказать исполнителю проекта?<\/p>\n<p>У аналитиков в этой области может быть слепая зона — нам-то на картине выше все понятно. А в прямые задачи датавиз-спеца входит проинтерпретировать запрос пользователя в контексте существующего функционала и создать визуализацию на стыке предпочтений заказчика и здравого смысла.<\/p>\n<p>Важно определить и причины этих проблем. Иногда ошибки — просто неудачная попытка выполнить запрос заказчика. Конечно, всегда можно отмести «плохой» запрос и сделать, как правильно — но тогда можно потерять важные для заказчика функции.<\/p>\n<p><b>Проблемы этого дашборда:<\/b><\/p>\n<ul>\n<li>Основной график — скаттерплот с SLA для всех лидов — выстроен на логарифмической шкале по оси Y без возможности переключиться на линейную. Есть сомнения, что все сейлз-менеджеры, глядя на дашборд, понимают, как работает логарифмическая шкала.<\/li>\n<li>При выборе гранулярности по неделям масштаб позволяет показать распределение точек на оси X по дням — но они распределены случайно с помощью функции RANDOM().<\/li>\n<li>Ось Y не синхронизирована между графиками, поэтому сложно оценить связь всех трех значений.<\/li>\n<li>Невозможно сравнить медианный SLA по следующим параметрам: курс, источник лида, команда, сейлз-менеджер — все они расположены в фильтрах. Сравнение требует скриншотов разных отображений или нескольких вкладок с одним дашбордом.<\/li>\n<\/ul>\n<p><b>Установленные причины:<\/b><\/p>\n<ul>\n<li>Логарифмическая шкала: заказчик, который являлся только одним из юзеров дашборда, попросил реализовать логарифмическую шкалу, чтобы смотреть на значения SLA, близкие к нулю. Видимо, это было релевантно для целей именно его отдела.<\/li>\n<li>Рандомное распределение по оси X: попытка сделать график проще и красивее, потому что скаттерплот уже перегружен информацией, и оценить распределение значений внутри недели — не приоритет.<\/li>\n<li>Неэффективные фильтры: до ввода дашборда заказчик не знал, какие именно сравнения окажутся ему полезны.<\/li>\n<\/ul>\n<p>Итог — невозможно оценить общую картину SLA в компании в отдельно взятый период, а значит и корректировать процессы и стратегии продаж.<\/p>\n<h2>Решение<\/h2>\n<p>Наш датавиз-специалист рисовал макеты карандашом на бумаге, а после утверждения переносил в Tableau: аналитический функционал и UX-дизайн для готового дашборда можно оптимизировать и без специальных тулов. Здесь хорошо ориентироваться на заказчика: если ему приятнее смотреть на файл в Figma — замечательно. Все понятно и на бумаге — отлично.<\/p>\n<p><b>Предложенные изменения:<\/b><\/p>\n<ul>\n<li>Фильтры справа сделать бар-чартами вместо выпадающих меню, чтобы разбивку по категориям было сразу видно.<\/li>\n<li>Реорганизовать дашборд в соответствии с принципами дизайна, учитывающими движение глаз человека слева-направо, сверху-вниз.<\/li>\n<li>Добавить линейную ось на скаттерплот, сделать именно ее форматом по умолчанию. Оставить возможность переключиться на логарифмическую ось.<\/li>\n<li>Нормализовать шкалу X, убрав рандомное распределение точек.<\/li>\n<\/ul>\n<h2>Версия 2: рабочая версия после переверстки<\/h2>\n<p><img src=http:\/\/test.leftjoin.ru\/pictures\/2-31.png  border=“0” width=100% height=100%><\/p>\n<p><b>Что поменялось:<\/b><\/p>\n<ul>\n<li>В левой части дашборда появилась таблица-фильтр по командам и сейлз-менеджерам. По ней можно оценить показатели работы отдельных сотрудников и отделов и получить общее представление о том, как обстоят дела с SLA в компании — а именно это изначальное назначение дашборда.<\/li>\n<li>В центральной части дашборда остался скаттерплот с SLA по всем лидам, только теперь формат отображения оси (линейная или логарифмическая) можно переключить.<\/li>\n<li>Фильтры курсов, источников лидов и категорий превратились в кликабельные бар-чарты в правой части экрана. Они позволяют сразу визуально оценить медианный SLA по этим параметрам.<\/li>\n<li>Все глобальные фильтры по категориям, которые нет необходимости сравнивать между собой, оказались в верхней части дашборда, там же — фильтр по дате. Теперь пространство экрана организовано эффективнее.<\/li>\n<\/ul>\n<p><b>Фидбэк:<\/b><\/p>\n<ul>\n<li>Потерялся график по средней длительности первого звонка.<\/li>\n<li>На центральном графике исчезли отсечки с медианным SLA.<\/li>\n<li>Не подписаны столбцы в таблице слева.<\/li>\n<li>Центральный скаттерплот очень долго загружается при первом открытии дашборда, так как Tableau пытается вывести все лиды из датасета — по умолчанию ни один фильтр не применяется и никак не ограничивает количество информации для отображения.<\/li>\n<li>Необходимы мелкие правки по оформлению и тултипам.<\/li>\n<\/ul>\n<h2>Версия 3: доработки и брендирование<\/h2>\n<p><img src=http:\/\/test.leftjoin.ru\/pictures\/3-27.png  border=“0” width=100% height=100%><\/p>\n<p><b>Что поменялось:<\/b><\/p>\n<ul>\n<li>В таблице слева появились подписи столбцов — теперь половина информации о работе отделов понятна при первом взгляде на дашборд.<\/li>\n<li>Центральный скаттерплот теперь отображается только после выбора фильтра по команде или конкретному сейлзу — это снижает нагрузку на хранилище и сильно ускоряет загрузку графика.<\/li>\n<li>Добавились отсечки с медианным SLA за конкретный период (месяц, неделю или день в зависимости от выбранной гранулярности).<\/li>\n<li>Вернулся график с длительностью первого звонка.<\/li>\n<li>Ось времени всех трех графиков теперь синхронизирована — не нужно сверять единицы измерения, чтобы выявить общие тренды.<\/li>\n<\/ul>\n<p>Когда функционал доработан и утвержден, вводится <b>брендирование<\/b> по корпоративным гайдлайнам. Они у Refocus выглядели так:<\/p>\n<p><img src=http:\/\/test.leftjoin.ru\/pictures\/image-1.png  border=“0” width=100% height=100%><\/p>\n<h2>Обзор функционала<\/h2>\n<p>Итоговый дашборд стал гораздо проще в использовании и настройке, а функционал стал интуитивно понятен.<\/p>\n<p>Так выглядит финальный дашборд при открытии, пока не выбран ни один фильтр:<\/p>\n<p><img src=http:\/\/test.leftjoin.ru\/pictures\/final.png  border=“0” width=100% height=100%><\/p>\n<p>А так, если выбрать сейлз-менеджера из таблицы слева:<\/p>\n<p><img src=http:\/\/test.leftjoin.ru\/pictures\/leads.png  border=“0” width=100% height=100%><\/p>\n<p>Использование фильтров справа (например, отобразить только лидов, пришедших с вебинаров):<\/p>\n<p><img src=http:\/\/test.leftjoin.ru\/pictures\/web.png  border=“0” width=100% height=100%><\/p>\n<p>Тултипы со ссылкой на первоисточник на скаттерплоте с лидами (время в них отображается в минутах при выборе любой шкалы):<\/p>\n<p><img src=http:\/\/test.leftjoin.ru\/pictures\/tip.png  border=“0” width=100% height=100%><\/p>\n<p>Наконец, переключение между линейной и логарифмической шкалами:<\/p>\n<p><img src=http:\/\/test.leftjoin.ru\/pictures\/log.png.jpg  border=“0” width=100% height=100%><\/p>\n<p>Этот кейс отлично демонстрирует важность чуткой работы с заказчиком. Всегда важен баланс между экспертностью и ориентацией на пользователя. Конечно, стоит показывать ему разные возможности и предлагать оптимальные с технической точки зрения решения. Но не менее важно доверять клиенту и разбираться в причинах его запросов, чтобы сделать по-настоящему полезно и красиво. Скажем, вдруг он просит логарифмическую шкалу не потому, что не подумал о других, а потому, что без нее в его отделе не обойтись? Внимание к таким моментам — огромный плюс к компетенциям аналитика.<\/p>\n",
            "date_published": "2024-09-04T15:44:06+03:00",
            "date_modified": "2024-09-04T15:43:37+03:00",
            "image": "http:\/\/test.leftjoin.ru\/pictures\/1-32.png",
            "_date_published_rfc2822": "Wed, 04 Sep 2024 15:44:06 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "147",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [],
                "og_images": [
                    "http:\/\/test.leftjoin.ru\/pictures\/1-32.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/2-31.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/3-27.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/image-1.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/0oblogka.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/final.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/leads.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/web.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/tip.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/log.png.jpg"
                ]
            }
        },
        {
            "id": "112",
            "url": "http:\/\/test.leftjoin.ru\/all\/zemfira-tableau\/",
            "title": "Анализ альбомов Земфиры: дашборд в Tableau",
            "content_html": "<p><a href=\"http:\/\/test.leftjoin.ru\/tableau\/zemfira.html\" style=\"text-decoration:none; border:0\"><img src=\"http:\/\/test.leftjoin.ru\/pictures\/zemfira.png.jpg\" border=\"0\" width=\"150%\" height=\"150%\"><\/a><\/p>\n<p>В марте мы опубликовали исследование <a href=\"http:\/\/test.leftjoin.ru\/all\/borderline-text-analysis\/\" class=\"nu\">«<u>Python и тексты нового альбома Земфиры: анализируем суть песен<\/u>»<\/a>, в котором при помощи Word2Vec-модели проанализировали близость песен альбома «бордерлайн» и получили самые близкие слова по духу альбома — ими оказались «пламень», «гореть», «тоска», «печаль», «сердце», «солнце» и другие.<\/p>\n<p>Мы продолжили работу над альбомами Земфиры и проанализировали семь из них, а затем результаты собрали в один дашборд и опубликовали его в <a href=\"http:\/\/test.leftjoin.ru\/tableau\/zemfira.html\">Tableau Public<\/a>. Посмотрите, что получилось.<\/p>\n<p>Заглавная страница — общий анализ семи альбомов Земфиры. Переключиться на конкретный альбом можно по нажатию на его иконку внизу страницы. Для каждого альбома представлена матрица семантической близости песен, облако слов и топ схожих слов для альбома.<\/p>\n",
            "date_published": "2021-07-08T13:56:12+03:00",
            "date_modified": "2021-07-08T13:43:32+03:00",
            "image": "http:\/\/test.leftjoin.ru\/pictures\/zemfira.png.jpg",
            "_date_published_rfc2822": "Thu, 08 Jul 2021 13:56:12 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "112",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [],
                "og_images": [
                    "http:\/\/test.leftjoin.ru\/pictures\/zemfira.png.jpg"
                ]
            }
        },
        {
            "id": "101",
            "url": "http:\/\/test.leftjoin.ru\/all\/coinkeeper-data-bot\/",
            "title": "Бот для преобразования данных из Coinkeeper",
            "content_html": "<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/@2x-copy.png.jpg\" width=\"2560\" height=\"1707\" alt=\"\" \/>\n<\/div>\n<p><a href=\"https:\/\/about.coinkeeper.me\">Coinkeeper<\/a> — кроссплатформенное приложение для учёта финансов. Внутри можно выпустить виртуальную банковскую карту Visa с бесплатным годовым обслуживанием, которая будет присылать уведомления, если вы тратите больше, чем запланировали. Помимо уведомлений, приложение ведёт историю трат и позволяет выгрузить сводный отчёт в формате csv. Данные, которое выгружает приложение ещё не готовы к анализу и выглядят так:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/1-27.png\" width=\"846\" height=\"647\" alt=\"\" \/>\n<\/div>\n<p>Азат Шарипов сделал скрипт обработки данных в пригодный для Tableau вид и подготовил <a href=\"https:\/\/public.tableau.com\/profile\/azat3313#!\/vizhome\/CoinKeeperanalytics\/Dashboard1\">Tableau Public книгу<\/a>, а <a href=\"https:\/\/t.me\/revealthedata\">Рома Бунин<\/a> в рамках своего проекта «Переверстка» <a href=\"https:\/\/public.tableau.com\/profile\/roman4734#!\/vizhome\/CoinKeeper\/CoinKeeper\">переработал дашборд<\/a>.<\/p>\n<p>Мы решили тоже поучаствовать, и с нашей стороны Елизавета Мазурова сделала <a href=\"https:\/\/t.me\/coinkeeper_export_bot\">чат-бота<\/a>.<\/p>\n<p>Чат-бот крутой! Помимо того, что он может как и прежде отдавать обратно .csv-файл, он позволяет автоматизировать рутину по обновлению отчета через Google-таблицы. Как, наверное, многие помнят, Tableau Public может работать на гугл-таблицах или csv файлах, но не разрешает подключение к данным. Бот умный: он создаст за вас гугл-таблицу и когда вы повторно отправите ему новый файл обновит ее.<\/p>\n<h2>Использование бота<\/h2>\n<p>Перейдите в диалог с <a href=\"https:\/\/t.me\/coinkeeper_export_bot\">ботом<\/a> и введите команду \/start — в ответе бот расскажет немного о себе. Для продолжения работы нажмите на кнопку «Начать».<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/2-26.png\" width=\"717\" height=\"184\" alt=\"\" \/>\n<\/div>\n<p>Сразу после можно отправить csv-файл, выгруженный из Coinkeeper:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/3-22.png\" width=\"489\" height=\"58\" alt=\"\" \/>\n<\/div>\n<p>Выберите тип файла — csv или таблицу в Google Spreadsheets.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/4-13.png\" width=\"782\" height=\"174\" alt=\"\" \/>\n<\/div>\n<p>В случае выбора csv-файла бот пришлёт его:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/5-14.png\" width=\"481\" height=\"115\" alt=\"\" \/>\n<\/div>\n<p>А в случае ссылки в первый раз нужно будет пройти небольшую регистрацию — указать почту и наименование для файла.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/6-14.png\" width=\"524\" height=\"56\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/7-8.png\" width=\"477\" height=\"57\" alt=\"\" \/>\n<\/div>\n<p>Затем бот пришлёт ссылку на файл:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/8-9.png\" width=\"666\" height=\"119\" alt=\"\" \/>\n<\/div>\n<p>Скрипт преобразовал данные, и таблицу можно указать в качестве источника данных в Tableau. А благодаря тому, что в случае загрузки нового файла создаётся не новая таблица, а обновляется старая, отчёт в Tableau тоже обновится. В результате открывается возможность еженедельно присылать боту новую таблицу и сразу переходить в обновлённый отчёт.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/9-8.png\" width=\"1217\" height=\"432\" alt=\"\" \/>\n<\/div>\n",
            "date_published": "2021-03-09T17:28:36+03:00",
            "date_modified": "2021-03-09T17:13:54+03:00",
            "image": "http:\/\/test.leftjoin.ru\/pictures\/0@2x.jpeg",
            "_date_published_rfc2822": "Tue, 09 Mar 2021 17:28:36 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "101",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [],
                "og_images": [
                    "http:\/\/test.leftjoin.ru\/pictures\/0@2x.jpeg",
                    "http:\/\/test.leftjoin.ru\/pictures\/@2x.png-1.jpg",
                    "http:\/\/test.leftjoin.ru\/pictures\/@2x-copy.png.jpg",
                    "http:\/\/test.leftjoin.ru\/pictures\/1-27.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/2-26.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/3-22.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/4-13.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/5-14.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/6-14.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/7-8.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/8-9.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/9-8.png"
                ]
            }
        },
        {
            "id": "91",
            "url": "http:\/\/test.leftjoin.ru\/all\/radial-pie-v-tableau\/",
            "title": "Radial pie в Tableau",
            "content_html": "<p>Как-то раз на просторах YouTube мы нашли вот такое видео с гайдом по Radial Pie в Tableau:<\/p>\n<div class=\"e2-text-video\">\n<iframe src=\"https:\/\/www.youtube.com\/embed\/w6qEG7AyDYo\" frameborder=\"0\" allowfullscreen><\/iframe><\/div>\n<p>Нам очень понравилась реализация — диаграмма сильно напоминает кольца активности Apple Watch. Но, к сожалению, по задумке графика кольца останавливаются на 270 градусах. Показываем, как сделать максимально приближенную к кольцам активности реализацию.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/rings.png\" width=\"476\" height=\"459\" alt=\"\" \/>\n<div class=\"e2-text-caption\">Кольца активности в Apple Watch<\/div>\n<\/div>\n<h2>Подготовка данных<\/h2>\n<p class=\"note\">Данная визуализация является весьма спорной в контексте бизнес-дашбордов<\/p>\n<p>Загрузим датасорс в Tableau. Наши кольца — это круги из 360 точек, и для каждой нам нужно своё наблюдение. Это легко реализовать при помощи Bins: сначала перетянем файл под поле с этим же файлом, чтобы объединить датасет с самим собой. В результате датасет должен «удвоиться» и появится новое поле с наименованием файла.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/--2021-01-21--16.25.48.png\" width=\"507\" height=\"277\" alt=\"\" \/>\n<\/div>\n<p>Создадим новое вычисляемое поле и назовем его Path.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/2-20.png\" width=\"496\" height=\"129\" alt=\"\" \/>\n<\/div>\n<p>Затем перейдём на график. Кликнем правой кнопкой мыши по Path из раздела Measures и создадим из этого поля Bins. Size of bins установим на единицу:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/4-11.png\" width=\"541\" height=\"247\" alt=\"\" \/>\n<\/div>\n<p>Создадим новое вычисляемое поле Index:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/5-11.png\" width=\"292\" height=\"133\" alt=\"\" \/>\n<\/div>\n<p>И поле Percentage, которое отобразит, насколько выполнены цели. Если достижение по цели будет больше самой цели, мы отобразим 1, чтобы не появлялись значения больше единицы.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/6-11.png\" width=\"469\" height=\"122\" alt=\"\" \/>\n<\/div>\n<p>Теперь создаём следующие меры:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/7-6.png\" width=\"258\" height=\"111\" alt=\"\" \/>\n<\/div>\n<p>wc_start — мера начальной координаты каждого кольца. Она считается по полю Order, соответственно, у Stand Order равен 1, а значит начинаться это кольцо будет раньше всех, в точке 1 по OY. У кольца Exercise Order равен 2, оно будет в середине. У Move Order равен 3 — это кольцо будет внешним и начнётся в точке 3.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/8-7.png\" width=\"259\" height=\"116\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/9-7.png\" width=\"262\" height=\"95\" alt=\"\" \/>\n<\/div>\n<p>percentage_label — мера для Label, в которой записано процентное отношение достижения по цели к самой цели:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/9.1.png\" width=\"293\" height=\"118\" alt=\"\" \/>\n<\/div>\n<p>Y2 — вспомогательная мера для начальных точек колец:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/14-3.png\" width=\"253\" height=\"100\" alt=\"\" \/>\n<\/div>\n<p>Наконец, финальные поля X и Y. Если значение меньше 360, мы описываем при помощи синуса внутреннюю линию кольца, если больше — то внешнюю линию, иначе — острие, на котором кончается кольцо. Формула вычисления Y аналогична X, но считаем не синус, а косинус.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/10-7.png\" width=\"562\" height=\"215\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/11-6.png\" width=\"575\" height=\"234\" alt=\"\" \/>\n<\/div>\n<h2>Визуализация<\/h2>\n<p>Измерение Path (bin) перетянем в поле Detail, X — в Columns, а Y — в Rows. X и Y должны вычисляться при помощи Path:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/12-4.png\" width=\"631\" height=\"388\" alt=\"\" \/>\n<\/div>\n<p>Тип графика сменим с Automatic на Polygon и перетянем меру Index в поле Path. Поле Description перетягиваем в Color.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/13-4.png\" width=\"818\" height=\"734\" alt=\"\" \/>\n<\/div>\n<p>Меру Y2 тоже перетягиваем в Rows и устанавливаем для оси Dual Axis. Из All в Marks необходимо удалить Measure Names. Правой кнопкой мыши кликаем на ОY и синхронизируем оси:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/--2021-01-21--15.07.33.png\" width=\"221\" height=\"185\" alt=\"\" \/>\n<\/div>\n<p>Для Y2 устанавливаем тип Circle и корректируем размер:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/123.png\" width=\"949\" height=\"462\" alt=\"\" \/>\n<\/div>\n<h2>Работа над оформлением<\/h2>\n<p>В Tableau есть возможность самому подобрать нужную гамму. Для жмём на Colors, затем на Edit colors, выбираем нужное поле и указываем цвет. Для гаммы колец из WatchOS мы подобрали такие цвета:<\/p>\n<ol start=\"1\">\n<li>Красный: rgb(229, 54, 83)<\/li>\n<li>Зелёный: rgb(186, 252, 79)<\/li>\n<li>Синий: rgb(117, 229, 228)<\/li>\n<\/ol>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/--2021-01-21--15.11.25.png\" width=\"391\" height=\"251\" alt=\"\" \/>\n<\/div>\n<p>В Label Y2 перетягиваем поля Description и percentage_label. Устанавливаем выравнивание, Description выделяем жирным цветом, ставим галочку в Options у поля Allow labels to overlap other marks, чтобы Label был виден:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/--2021-01-21--15.14.59.png\" width=\"498\" height=\"404\" alt=\"\" \/>\n<\/div>\n<p>Скрываем все линии, границы и индикатор, заливаем фон чёрным цветом. Результат — такая диаграмма:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/--2021-01-21--15.17.58.png\" width=\"670\" height=\"678\" alt=\"\" \/>\n<\/div>\n<p>Книга и таблица из примера доступны в <a href=\"https:\/\/github.com\/valiotti\/leftjoin\/tree\/master\/active_rings_tableau\">нашем репозитории<\/a> на GitHub.<\/p>\n",
            "date_published": "2021-01-21T18:18:55+03:00",
            "date_modified": "2021-01-25T16:44:32+03:00",
            "image": "http:\/\/test.leftjoin.ru\/pictures\/1-20.png",
            "_date_published_rfc2822": "Thu, 21 Jan 2021 18:18:55 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "91",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [],
                "og_images": [
                    "http:\/\/test.leftjoin.ru\/pictures\/1-20.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/2-19.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/3-18.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/4-10.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/6-10.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/10-6.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/11-5.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/12-3.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/13-3.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/1-21.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/remote\/youtube-w6qEG7AyDYo-cover.jpg",
                    "http:\/\/test.leftjoin.ru\/pictures\/rings.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/--2021-01-21--16.25.48.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/2-20.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/4-11.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/5-11.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/6-11.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/7-6.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/8-7.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/9-7.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/9.1.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/14-3.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/10-7.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/11-6.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/12-4.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/13-4.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/--2021-01-21--15.07.33.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/123.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/--2021-01-21--15.11.25.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/--2021-01-21--15.14.59.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/--2021-01-21--15.17.58.png"
                ]
            }
        },
        {
            "id": "90",
            "url": "http:\/\/test.leftjoin.ru\/all\/funnel-chart-v-tableau\/",
            "title": "Funnel chart в Tableau",
            "content_html": "<p>Диаграмма в виде воронки — хороший выбор визуализации, если стоит задача отобразить достижение целей по ряду этапов. Сегодня мы посмотрим, как получить такую диаграмму в Tableau.<\/p>\n<p class=\"note\">Таблица из примера доступна в нашем <a href=\"https:\/\/github.com\/valiotti\/leftjoin\/tree\/master\/tableau-funnel\">репозитории<\/a> на GitHub<\/p>\n<p>Данные должны быть представлены в следующем виде, и если вы получаете их при помощи Custom SQL Query, вам может быть полезен наш последний материал: <a href=\"http:\/\/test.leftjoin.ru\/all\/unpivot-with-cross-join\/\" class=\"nu\">«<u>UNPIVOT данных с использованием CROSS JOIN<\/u>»<\/a>.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/1-19.png\" width=\"292\" height=\"440\" alt=\"\" \/>\n<\/div>\n<p>В таблице из примера мы получим 6 разных этапов: Identify, Pursue, Contact, Proposal, Negotiation и Won. Для каждого нужно задать соответствующее вычисляемое поле: например, ниже описана формула для вычисляемого поля статуса Identify.<\/p>\n<pre class=\"e2-text-code\"><code>if ATTR([Status]) = 'Identify' or LOOKUP(ATTR([Status]), -1)=&quot;Identify&quot; then SUM([Value]) END<\/code><\/pre><div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/2-18.png\" width=\"848\" height=\"333\" alt=\"\" \/>\n<\/div>\n<p>Итого должно получиться 6 новых мер:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/3-17.png\" width=\"200\" height=\"290\" alt=\"\" \/>\n<\/div>\n<p>Перетяните Measure Values в верхнюю часть графика: должен получиться такой bar chart:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/4-9.png\" width=\"1064\" height=\"201\" alt=\"\" \/>\n<\/div>\n<p>Над графиком в выпадающем меню отображения графиков поменяйте Standart на Entrie View — график должен в ответ расшириться:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/5-10.png\" width=\"115\" height=\"100\" alt=\"\" \/>\n<\/div>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/6-9.png\" width=\"1066\" height=\"747\" alt=\"\" \/>\n<\/div>\n<p>Из Measure Values удалите меры CNT(Sheet) и SUM(Value), которые не относятся к воронке:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/7-5.png\" width=\"161\" height=\"250\" alt=\"\" \/>\n<\/div>\n<p>Измерение Status перенесите в поле Rows. Получится несколько столбиков — это и есть будущие этапы воронки:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/8-6.png\" width=\"1070\" height=\"745\" alt=\"\" \/>\n<\/div>\n<p>Убедитесь, что все вычисляемые поля вычислены при помощи Table (down):<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/9-6.png\" width=\"329\" height=\"288\" alt=\"\" \/>\n<\/div>\n<p>А Stack marks установлен на off:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/10-5.png\" width=\"408\" height=\"143\" alt=\"\" \/>\n<\/div>\n<p>Смените тип графика на Area:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/11-4.png\" width=\"1226\" height=\"748\" alt=\"\" \/>\n<\/div>\n<p>Чтобы каждый этап был окрашен в собственный цвет, перенесите измерение Status в поле Color:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/12-2.png\" width=\"1225\" height=\"814\" alt=\"\" \/>\n<\/div>\n<p>В фильтре Status справа отсортируйте этапы по убыванию, перетягивая левой кнопкой мыши в нужное место:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/13-2.png\" width=\"1062\" height=\"731\" alt=\"\" \/>\n<\/div>\n<p>Зажав клавишу CMD на MacOS или Ctrl на Windows, зажмите левой клавишей мыши Measures Values в поле Columns и протяните в область рядом: должно появиться такое же, а на графике с воронкой рядом должен появиться идентичный график.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/14-2.png\" width=\"910\" height=\"812\" alt=\"\" \/>\n<\/div>\n<p>Нажмите на ось X у левого графика и перейдите в меню Edit Axis. В разделе Scale поставьте галочку на поле Reversed, чтобы «отзеркалить» левый график.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/15-1.png\" width=\"241\" height=\"112\" alt=\"\" \/>\n<\/div>\n<p>Получится такая диаграмма:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/16-1.png\" width=\"909\" height=\"744\" alt=\"\" \/>\n<\/div>\n<p>Поработаем над оформлением. Нажмите правой кнопкой мыши на область с наименованием этапов слева и поставьте галочку напротив «Show Header». Проделайте то же самое с осью внизу:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/17-1.png\" width=\"183\" height=\"203\" alt=\"\" \/>\n<\/div>\n<p>Скройте также индикатор внизу:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/18-1.png\" width=\"206\" height=\"64\" alt=\"\" \/>\n<\/div>\n<p>Нажмите правой кнопкой мыши по графику и перейдите в раздел Format. Перейдите в меню Format Lines и смените значение для каждого типа линий на None. В соседнем разделе Format Borders также везде установите None:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/19-2.png\" width=\"200\" height=\"365\" alt=\"\" \/>\n<\/div>\n<p>Затем перенесите измерение Status и меру Value в поле Label. Нажмите на SUM(VALUE) и перейдите в Add Table Calculation, чтобы добавить ещё процент от первого этапа. В поле Calculation Type выберите «Percent From», а в поле Relative to — «First». Чтобы отобразить на каждом этапе процент от предыдущего: нажмите правой кнопкой мыши по мере SUM(Value) и нажмите на Add Table Calculation. В поле Calculation Type выберите «Percent From», а в поле Relative to — «Previous».<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/19.5.png\" width=\"342\" height=\"433\" alt=\"\" \/>\n<\/div>\n<p>После нажмите на Label, перейдите в Edit Label и расположите текст с процентным соотношением под статусом:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/20-2.png\" width=\"602\" height=\"372\" alt=\"\" \/>\n<\/div>\n<p>Выравнивание установите, как на скриншоте:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/20.5.png\" width=\"344\" height=\"371\" alt=\"\" \/>\n<\/div>\n<p>Ещё перенесите в Tooltip меру Value, чтобы отображать в нём абсолютные значения. Затем нажмите на Tooltip и поменяйте форматирование:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/21-1.png\" width=\"602\" height=\"468\" alt=\"\" \/>\n<\/div>\n<p>В итоге получится такой график, у которого в подсказках отображается значение по этапу, процент от прошлого этапа и процент от первого этапа:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/22-1.png\" width=\"1066\" height=\"746\" alt=\"\" \/>\n<\/div>\n<p>На написание этой статьи нас вдохновил <a href=\"https:\/\/www.youtube.com\/watch?v=7fBNcgGVaoQ\">анлоязычный видеорецепт<\/a>.<\/p>\n",
            "date_published": "2021-01-13T16:55:16+03:00",
            "date_modified": "2021-01-14T19:04:53+03:00",
            "image": "http:\/\/test.leftjoin.ru\/pictures\/1-19.png",
            "_date_published_rfc2822": "Wed, 13 Jan 2021 16:55:16 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "90",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css"
                ],
                "og_images": [
                    "http:\/\/test.leftjoin.ru\/pictures\/1-19.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/2-18.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/3-17.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/4-9.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/5-10.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/6-9.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/7-5.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/8-6.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/9-6.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/10-5.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/11-4.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/12-2.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/13-2.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/14-2.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/15-1.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/16-1.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/17-1.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/18-1.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/19-2.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/19.5.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/20-2.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/20.5.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/21-1.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/22-1.png"
                ]
            }
        },
        {
            "id": "89",
            "url": "http:\/\/test.leftjoin.ru\/all\/unpivot-with-cross-join\/",
            "title": "UNPIVOT данных с использованием CROSS JOIN",
            "content_html": "<p>Зачастую мы получаем данные в предагрегированном виде, когда каждая отдельная колонка является посчитанной метрикой. По аналогии мы получаем подобный результат, когда строим сводную таблицу в Excel и используем некоторое количество фактов для агрегации. Но что делать, если нам нужно произвести обратную операцию — Unpivot?<\/p>\n<p>Как поступить, если в датасете понадобилось трансформировать данные в реляционный вид? В Tableau есть фича <a href=\"https:\/\/help.tableau.com\/current\/pro\/desktop\/en-us\/pivot.htm\">Unpivot<\/a>, которая сделает всё сама: если датасет построен из файла, достаточно выделить нужные колонки и нажать на кнопку «Pivot». А в некоторых диалектах SQL, например, в Transact, уже есть <a href=\"https:\/\/docs.microsoft.com\/ru-ru\/sql\/t-sql\/queries\/from-using-pivot-and-unpivot\">встроенные функции<\/a>, которые тоже делают это сами.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/qs_pivot_example.png\" width=\"650\" height=\"263\" alt=\"\" \/>\n<\/div>\n<p>Но в случае, если датасет построен на Custom SQL Query из базы данных, у которой в арсенале отсутствуют встроенные функции для трансформации в сводную и обратно, необходим какой-то другой подход, и Tableau порекомендует для такой таблицы:<\/p>\n<div class=\"e2-text-table\">\n<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n<tr>\n<td><b>ID<\/b><\/td>\n<td><b>a<\/b><\/td>\n<td><b>b<\/b><\/td>\n<td><b>c<\/b><\/td>\n<\/tr>\n<tr>\n<td>1<\/td>\n<td>a1<\/td>\n<td>b1<\/td>\n<td>c1<\/td>\n<\/tr>\n<tr>\n<td>2<\/td>\n<td>a2<\/td>\n<td>b2<\/td>\n<td>c2<\/td>\n<\/tr>\n<\/table>\n<\/div>\n<p>Воспользоваться таким стандартным универсальным, но не очень эффективным решением:<\/p>\n<pre class=\"e2-text-code\"><code>select id, ‘a’ AS col, a AS value\r\nfrom yourtable\r\nunion all\r\nselect id, ‘b’ AS col, b AS value\r\nfrom yourtable\r\nunion all\r\nselect id, ‘c’ AS col, c AS value\r\nfrom yourtable<\/code><\/pre><p>И в результате получить таблицу вида:<\/p>\n<div class=\"e2-text-table\">\n<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n<tr>\n<td><b>id<\/b><\/td>\n<td><b>col<\/b><\/td>\n<td><b>value<\/b><\/td>\n<\/tr>\n<tr>\n<td>1<\/td>\n<td>a<\/td>\n<td>a1<\/td>\n<\/tr>\n<tr>\n<td>2<\/td>\n<td>a<\/td>\n<td>a2<\/td>\n<\/tr>\n<tr>\n<td>1<\/td>\n<td>b<\/td>\n<td>b1<\/td>\n<\/tr>\n<tr>\n<td>2<\/td>\n<td>b<\/td>\n<td>b2<\/td>\n<\/tr>\n<tr>\n<td>1<\/td>\n<td>c<\/td>\n<td>c1<\/td>\n<\/tr>\n<tr>\n<td>2<\/td>\n<td>c<\/td>\n<td>c2<\/td>\n<\/tr>\n<\/table>\n<\/div>\n<p>Порой, когда мы работаем с физической таблицей и нам надо быстро получить результаты для двух-трех колонок, действительно, подобное решение можно быстро применить, не задумываясь. Однако в случае, когда вместо таблицы содержится, например, сложный подзапрос с несколькими джойнами и нужно сделать Pivot для 5+ колонок, подзапрос вызовется целых 5+ раз, согласитесь, не очень действенно считать одно и тоже неоднократно. Вместо этого можно воспользоваться рецептом с CROSS JOIN, найденным на просторах Stack Overflow:<\/p>\n<pre class=\"e2-text-code\"><code>select t.id,\r\nc.col,\r\n    case c.col\r\n        when 'a' then a\r\n        when 'b' then b\r\n        when 'c' then c\r\n    end as data\r\nfrom yourtable t\r\ncross join\r\n(\r\n    select 'a' as col\r\n    union all select 'b'\r\n    union all select 'c'\r\n) c<\/code><\/pre><p>Разберём запрос подробнее. CROSS JOIN — перекрёстное соединение, декартово произведение, или, проще говоря, произведение всех строк со всеми. За ненадобностью в синтаксисе CROSS JOIN отсутствует ON — мы объединяем не по какому-то конкретному полю две таблицы, а сразу по всем существующим строкам.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/Background_2.png\" width=\"730\" height=\"388\" alt=\"\" \/>\n<\/div>\n<p>Сначала мы формируем таблицу со всеми колонками, предназначенными для преобразования в строки. В нашем случае это колонки a, b и c: поэтому мы сделали таблицу c, в которой будет колонка col со значениями a, b и c:<\/p>\n<pre class=\"e2-text-code\"><code>(\r\n    select 'a' as col\r\n    union all select 'b'\r\n    union all select 'c'\r\n) c<\/code><\/pre><p>Выглядит она так:<\/p>\n<div class=\"e2-text-table\">\n<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n<tr>\n<td><b>col<\/b><\/td>\n<\/tr>\n<tr>\n<td>a<\/td>\n<\/tr>\n<tr>\n<td>b<\/td>\n<\/tr>\n<tr>\n<td>c<\/td>\n<\/tr>\n<\/table>\n<\/div>\n<p>Затем таблицы yourtable и c объединятся перекрестным соединением, а после мы возьмём поля id, col и в зависимости от того, как называется ячейка в col, подставим соответствующие данные в поле data.<\/p>\n<pre class=\"e2-text-code\"><code>select t.id,\r\nc.col,\r\n    case c.col\r\n        when 'a' then a\r\n        when 'b' then b\r\n        when 'c' then c\r\n    end as value\r\nfrom yourtable t\r\ncross join\r\n(\r\n    select 'a' as col\r\n    union all select 'b'\r\n    union all select 'c'\r\n) c<\/code><\/pre><p>В итоге получим ту же самую искомую таблицу, с которой уже можно удобно работать любым аналитическим инструментом:<\/p>\n<div class=\"e2-text-table\">\n<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n<tr>\n<td><b>id<\/b><\/td>\n<td><b>col<\/b><\/td>\n<td><b>value<\/b><\/td>\n<\/tr>\n<tr>\n<td>1<\/td>\n<td>a<\/td>\n<td>a1<\/td>\n<\/tr>\n<tr>\n<td>2<\/td>\n<td>a<\/td>\n<td>a2<\/td>\n<\/tr>\n<tr>\n<td>1<\/td>\n<td>b<\/td>\n<td>b1<\/td>\n<\/tr>\n<tr>\n<td>2<\/td>\n<td>b<\/td>\n<td>b2<\/td>\n<\/tr>\n<tr>\n<td>1<\/td>\n<td>c<\/td>\n<td>c1<\/td>\n<\/tr>\n<tr>\n<td>2<\/td>\n<td>c<\/td>\n<td>c2<\/td>\n<\/tr>\n<\/table>\n<\/div>\n",
            "date_published": "2021-01-08T16:30:14+03:00",
            "date_modified": "2021-01-08T16:31:33+03:00",
            "image": "http:\/\/test.leftjoin.ru\/pictures\/qs_pivot_example.png",
            "_date_published_rfc2822": "Fri, 08 Jan 2021 16:30:14 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "89",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css"
                ],
                "og_images": [
                    "http:\/\/test.leftjoin.ru\/pictures\/qs_pivot_example.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/Background_2.png"
                ]
            }
        },
        {
            "id": "87",
            "url": "http:\/\/test.leftjoin.ru\/all\/tableau-vs-powerbi-learning\/",
            "title": "Сравнение программ обучения Tableau и PowerBI",
            "content_html": "<p>В этом году мне удалось пройти сертификацию Tableau Desktop Associate. И когда я думал о том, как к ней лучше подготовиться, я наткнулся на курсы <a href=\"https:\/\/www.tableau.com\/learn\/training\/elearning\">elearning<\/a> от Tableau, которые ещё и оказались бесплатными на 90 дней.<\/p>\n<p>Я решил, что нельзя упускать такую возможность и решил пройти все три блока Fundamentals в бодром темпе. Когда получил сертификацию мне стало интересно, какие программы обучения предлагают другие производители BI-инструментов. И первым делом пошёл изучать обучающие материалы по PowerBI. В этой небольшой статье хочу попытаться сравнить программы обучения от Tableau и PowerBI.<\/p>\n<p class=\"note\">Дисклеймер: в итоге у меня сформировалось предвзятое положительное отношение к Tableau, поэтому сторонникам PowerBI данная статья может оказаться не по нраву и в чем-то окажется субъективной (справедливости ради слова похвалы PowerBI тоже присутствуют).<\/p>\n<p>В результате изучения обучающих материалов я, пожалуй, наконец, могу сформулировать, почему я все же голосую двумя руками за Tableau как за инструмент анализа и визуализации данных.<\/p>\n<p>Прежде всего, существует огромная пропасть в подходе к материалам и проверке их понимания. Несмотря на то, что обучающие материалы Tableau носят более технический характер и в меньшей степени уделяют внимание дизайну, обучаясь через их видео, всё же можно делать отличные рабочие визуализации. Что и говорить, после прохождения всех трёх ступеней обучения Tableau появляется желание творить новые крутые отчёты с использованием всех LOD Expressions, Filter Actions и создавать удобные интерфейсы. А вот после просмотра всех материалов по PowerBI остаётся один вопрос: зачем я потратил своё время? Для объективности сравнения и те, и другие материалы я изучал на английском языке. Думаю, в индустрии это стандарт, поскольку открыв 2-3 ссылки на русском понимаешь, что переведено это пяткой левой ноги.<\/p>\n<p>Если отбросить эмоции, есть несколько ключевых вещей, которые оказались принципиальны для меня в результате изучения материалов.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/1-18.png\" width=\"1265\" height=\"654\" alt=\"\" \/>\n<div class=\"e2-text-caption\">Так выглядит хороший дашборд по версии Microsoft<\/div>\n<\/div>\n<h2>Качество подготовки контента и примеров в обучении<\/h2>\n<p>Если посмотреть на логику изложения обучающих видео Tableau и вопросов в формате квиза, которые задаются в конце прохождения материала, начинаешь проникаться идеей софта. Но в случае с PowerBI тебя ждёт тотальное разочарование. Взгляните, к примеру, на <a href=\"https:\/\/docs.microsoft.com\/en-us\/learn\/modules\/perform-analytics-power-bi\/3-visuals\">материал об обнаружении выбросов<\/a>, тут Microsoft предлагает построить диаграмму scatter plot и визуально определить все выбросы на глаз.<\/p>\n<h2>Дизайн отчётов и дашбордов<\/h2>\n<p>Существуют достаточно объективные придирки к обучающим материалам Tableau на тему дизайна графиков и элементов управления, но всё равно они сделаны аккуратно и красиво. А теперь взгляните на <a href=\"https:\/\/docs.microsoft.com\/en-us\/learn\/modules\/visuals-in-power-bi\/12-formatting\">тот ужас<\/a>, который предлагает в качестве результата работы аналитика Microsoft. А вот <a href=\"https:\/\/docs.microsoft.com\/en-us\/learn\/modules\/create-dashboards-power-bi\/1-introduction\">хорошо построенный дашборд<\/a> по версии Microsoft.<\/p>\n<h2>Проверка полученных знаний из обучения<\/h2>\n<p>Во время обучения Tableau ты сразу же после небольшой лекции учишься применению куска изученного материала на практике. Нужно нажать конкретные кнопки в интерфейсе, чтобы решить задачу. В PowerBI предполагаются «лабораторные работы», которые должны были запуститься с удалённой машины. Мне не удалось начать ни одну лабораторную работу, я трижды писал в саппорт, саппорт так и не смог решить мою проблему, поэтому поэкспериментировать с заданиями в PowerBI у меня так и не вышло.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/3-16.png\" width=\"1279\" height=\"654\" alt=\"\" \/>\n<div class=\"e2-text-caption\">Результат работы аналитика по версии Microsoft<\/div>\n<\/div>\n<p>Следующие пункты больше относятся к самому софту, чем к программам обучения.<\/p>\n<h2>Кроссплатформенность<\/h2>\n<p>Я давно работаю с Tableau, и 4 года назад пересел на Mac. После перехода с Windows мой опыт использования Tableau никак не изменился: по сути, Tableau развивался, а я вместе с ним, но при этом ключевые элементы интерфейса команда не меняла. Я экспериментировал с построением отчётов в PowerBI, но мне были неудобны различные архаизмы Microsoft типа публикаций через какой-нибудь share-портал, где обязательно нужно иметь учётную запись MS и настраивать что-то через администратора. Вся эта головная боль жутко утомляет.<\/p>\n<p>Однако гораздо больше меня поразил тот факт, что я не могу воспользоваться PowerBI на Mac. Вообще, совсем никак, и это принципиальная позиция Microsoft, которая в ближайшем будущем не планируется меняться. С моей точки зрения, такое программное обеспечение относится к сегменту B2B в области аналитики, предполагает подключение ко всевозможным СУБД, но отрицает факт существования альтернативной операционной системы, на которой потенциальное n-ное количество консультантов могут продвигать и использовать PowerBI как аналитический инструмент.<\/p>\n<p>Наверняка есть рациональные причины, связанные с тем, что любой софт от Microsoft не очень здорово работает на Mac, но факт остаётся фактом: для меня софт становится недоступным. Тем не менее, я не искал лёгких путей и поставил PowerBI через Parallels для того, чтобы всё-таки честно посмотреть ещё раз на инструмент с учётом обучающих материалов.<\/p>\n<h2>Опции визуализации<\/h2>\n<p>И в Tableau, и в PowerBI очень крутые опции визуализации данных. К слову, в данном разрезе PowerBI всё же предлагает видео и <a href=\"https:\/\/docs.microsoft.com\/en-us\/learn\/modules\/visuals-in-power-bi\/\">чуть больше информации<\/a>, чем обычно. Так что по этой части инструменты представлены одинаково хорошо.<\/p>\n<h2>Функциональность<\/h2>\n<p>А тут хочется отдать должное функциональности PowerBI. Действительно, багаж инструментов даже без подключения сторонних библиотек крайне широкий. К примеру, <a href=\"https:\/\/docs.microsoft.com\/en-us\/learn\/modules\/perform-analytics-power-bi\/5-clustering-techniques\">автоматическая кластеризация<\/a>, <a href=\"https:\/\/docs.microsoft.com\/en-us\/learn\/modules\/ai-visuals-power-bi\/4-decomposition-tree\">Decomposition Tree<\/a>, <a href=\"https:\/\/docs.microsoft.com\/en-us\/learn\/modules\/clean-data-power-bi\/6-profile-data\">Data Profiler<\/a> или <a href=\"https:\/\/docs.microsoft.com\/en-us\/learn\/modules\/data-driven-story-power-bi\/6-advanced-interactions\">Настройка фильтров по графику<\/a><\/p>\n<h2>Синтаксис внутреннего языка<\/h2>\n<p>Для работы с PowerBI следует выучить DAX. Это не язык программирования, а функциональный язык. Что-то своё написать не получится, но оно и не понадобится — внутри уже реализованы все функции, которыми нужно только научиться правильно пользоваться. Microsoft неплохо рассказывает про DAX в <a href=\"https:\/\/docs.microsoft.com\/en-us\/learn\/modules\/dax-power-bi-write-formulas\/\">мануале<\/a>. Определение новой меры на языке DAX выглядит так:<\/p>\n<pre class=\"e2-text-code\"><code>Revenue YoY % =\r\nDIVIDE(\r\n\t[Revenue]\r\n\t\t- CALCULATE(\r\n\t\t\t[Revenue],\r\n\t\t\tSAMEPERIODLASTYEAR('Date'[Date])\r\n\t),\r\n\tCALCULATE(\r\n\t\t[Revenue],\r\n\t\tSAMEPERIODLASTYEAR('Date'[Date])\r\n\t)\r\n)<\/code><\/pre><h2>Подготовка данных к анализу<\/h2>\n<p>Внутри PowerBI есть фича <a href=\"https:\/\/docs.microsoft.com\/en-us\/learn\/modules\/clean-data-power-bi\/2-shape-data\">Unpivot<\/a>, которая позволяет привести данные, разложенные по столбцам с временными периодами к форме, удобной для использования в сводных таблицах:<\/p>\n<div class=\"e2-text-picture\">\n<div class=\"fotorama\" data-width=\"537\" data-ratio=\"1.7266881028939\">\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/02-original-data-ss.png\" width=\"537\" height=\"311\" alt=\"\" \/>\n<img src=\"http:\/\/test.leftjoin.ru\/pictures\/02-unpivot-ss.png\" width=\"528\" height=\"582\" alt=\"\" \/>\n<\/div>\n<\/div>\n<p>Впрочем, в ETL-инструменте для очистки и предобработки данных Tableau Prep такое тоже <a href=\"https:\/\/www.tableau.com\/about\/blog\/2019\/1\/new-tableau-prep-pivot-rows-columns-and-add-descriptions-any-change-99937 \">реализовано<\/a><\/p>\n<h2>Выводы:<\/h2>\n<p>1) Программы обучения построены совершенно по-разному, методология погружения в инструмент от Tableau намного продуманнее и эффективнее. Есть возможность сразу же получить практический опыт решения задач и получить обратную связь (хоть и автоматическую).<br \/>\n2) Дизайн отчетов и дашбордов в обучающих материалах от Microsoft выглядит едва ли профессионально, у Tableau реализация выглядит на порядок лучше<br \/>\n3) Реализация проверки знаний от Microsoft ниже плинтуса (совершенно формальные тесты как в плохой школе), у Tableau реализовано хорошо, погружаешься в задачу, думаешь над ответом и решаешь.<br \/>\n4) Кроссплатформенность явно не является коньком PowerBI, однако в случае Tableau это отличное конкурентное преимущество<br \/>\n5) Функциональность и возможности инструментов, разумеется, находятся на высоком уровне, и в чем-то победу одерживает PowerBI.<\/p>\n<p>Посмотрите наши обзоры дашбордов в <a href=\"http:\/\/test.leftjoin.ru\/all\/superstore-tableau\/\">Tableau<\/a>, <a href=\"http:\/\/test.leftjoin.ru\/all\/powerbi-guide\/\">PowerBI<\/a>, <a href=\"http:\/\/test.leftjoin.ru\/all\/datastudio-bi-guide\/\">Google Data Studio<\/a>, <a href=\"http:\/\/test.leftjoin.ru\/all\/sap-bi-guide\/\">SAP Analytics Cloud<\/a>, <a href=\"http:\/\/test.leftjoin.ru\/all\/obzor-dashborda-qliksense\/\">QlikSense<\/a>, <a href=\"http:\/\/test.leftjoin.ru\/all\/obzor-dashborda-v-redash\/\">Redash<\/a> и в других BI-системах.<\/p>\n",
            "date_published": "2020-12-25T13:05:32+03:00",
            "date_modified": "2020-12-25T14:30:26+03:00",
            "image": "http:\/\/test.leftjoin.ru\/pictures\/1-18.png",
            "_date_published_rfc2822": "Fri, 25 Dec 2020 13:05:32 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "87",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/fotorama\/fotorama.css",
                    "system\/library\/fotorama\/fotorama.js"
                ],
                "og_images": [
                    "http:\/\/test.leftjoin.ru\/pictures\/1-18.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/3-16.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/02-original-data-ss.png",
                    "http:\/\/test.leftjoin.ru\/pictures\/02-unpivot-ss.png"
                ]
            }
        },
        {
            "id": "82",
            "url": "http:\/\/test.leftjoin.ru\/",
            "title": "Матемаркетинг: сравнение BI-систем",
            "content_html": "<p>Недавно в блоге я публиковал первый доклад с Матемаркетинга — я упомянул, что докладов два, и сегодня выкладываю второй.<\/p>\n<p>Доклад был о сравнении дашбордов в разных BI-инструментах. Внутри — подробнейшее сравнение дашбордов в Tableau, PowerBI, Data Studio и Redash, построенных по одному макету: что можно реализовать в одних системах и с какими ограничениями придётся столкнуться в других, где и какие есть скрытые возможности, какие диаграммы визуально привлекательнее в конкретной BI-системе и прочее. Помимо различий в конце доклада можно посмотреть на таблицу оценок инструментов по нескольким критериям от нашей команды.<\/p>\n<div class=\"e2-text-video\">\n<iframe src=\"https:\/\/www.youtube.com\/embed\/zXhlbvEj30M\" frameborder=\"0\" allowfullscreen><\/iframe><\/div>\n<p>Кстати, подробный отдельный обзор на каждый BI-инструмент из приведённого и дополнительно обзоры на QlikSense и SAP Analytics Cloud уже <a href=\"http:\/\/test.leftjoin.ru\/all\/modern-bi-systems\/\">опубликованы в блоге<\/a>.<\/p>\n",
            "date_published": "2020-12-08T13:33:42+03:00",
            "date_modified": "2020-12-08T13:34:37+03:00",
            "image": "http:\/\/test.leftjoin.ru\/pictures\/remote\/youtube-zXhlbvEj30M-cover.jpg",
            "_date_published_rfc2822": "Tue, 08 Dec 2020 13:33:42 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "82",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [],
                "og_images": [
                    "http:\/\/test.leftjoin.ru\/pictures\/remote\/youtube-zXhlbvEj30M-cover.jpg"
                ]
            }
        },
        {
            "id": "70",
            "url": "http:\/\/test.leftjoin.ru\/all\/superstore-tableau\/",
            "title": "Обзор дашборда в Tableau",
            "content_html": "<p>В прошлый раз мы разобрались с <a href=\"http:\/\/test.leftjoin.ru\/all\/bi-task-canvas\/\">постановкой задачи<\/a>, построили макет и поставили цель спроектировать дашборд в Tableau по <a href=\"http:\/\/test.leftjoin.ru\/all\/pandas-profiling-2\/\">датасету SuperStore Sales<\/a>, который поможет понять среди каких регионов, продуктовых групп и клиентских сегментов формируется прибыль и каковы общие показатели деятельности за прошедшее время.<\/p>\n<p>В видео рассказываю весь процесс создания дашборда в первом рассматриваемом инструменте — Tableau: как мы подготавливали данные, создавали отчёты, верстали дашборд, с какими сложностями и правками столкнулись, а также как опубликовать его на сервере Tableau Public и насколько результат соответствует поставленной задаче.<\/p>\n<div class=\"e2-text-video\">\n<iframe src=\"https:\/\/www.youtube.com\/embed\/LKwqBy41E24\" frameborder=\"0\" allowfullscreen><\/iframe><\/div>\n<p>Мы оценили внутренней командой дашборд по критериям и получили следующие средние оценки (1 — худшая оценка, 10 — лучшая):<\/p>\n<ol>\r\n  <li><p title=\"1 – не отвечает, 10 – полностью отвечает\">Отвечает ли <a href=\"http:\/\/test.leftjoin.ru\/all\/bi-task-canvas\/\">заданным вопросам<\/a> — 10,0<\/p><\/li>\r\n  <li><p title=\"1 – высокий порог, 10 – низкий\">Порог входа в инструмент — 5,5<\/p><\/li>\r\n  <li><p title=\"1 – узкий функционал, 10 – широкий\">Функциональность инструмента — 9,0<\/p><\/li>\r\n  <li><p title=\"1 – дашборд неудобен, 10 – полностью удобен\">Удобство пользования — 8,5<\/p><\/li>\r\n  <li><p title=\"1 – результат не соответствует, 10 – соответствует полностью\">Соответствие результата макету — 10,0<\/p><\/li>\r\n  <li><p title=\"1 – дашборд непривлекателен, 10 – привлекателен\">Визуальная составляющая — 9,7<\/p><\/li>\r\n<\/ol>\n<p>Итог — дашборд на Tableau получает 8,8 баллов из 10 от нашей команды. <a href=\"http:\/\/test.leftjoin.ru\/bi-guide\/tableau-superstore.html\">Посмотрите на полученный результат.<\/a><\/p>\n<p>А что вы думаете о получившимся дашборде? Поставьте свои оценки в нашем Telegram-канале!<\/p>\n",
            "date_published": "2020-10-28T14:12:11+03:00",
            "date_modified": "2020-10-28T14:29:49+03:00",
            "image": "http:\/\/test.leftjoin.ru\/pictures\/remote\/youtube-LKwqBy41E24-cover.jpg",
            "_date_published_rfc2822": "Wed, 28 Oct 2020 14:12:11 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "70",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [],
                "og_images": [
                    "http:\/\/test.leftjoin.ru\/pictures\/remote\/youtube-LKwqBy41E24-cover.jpg"
                ]
            }
        }
    ],
    "_e2_version": 3365,
    "_e2_ua_string": "E2 (v3365; Aegea)"
}