Создание диаграммы с накоплением

У меня есть две таблицы, в которых хранятся попытки входа пользователей. Одна таблица содержит все успешные входы в систему, а другая - неудачные попытки. Я пытаюсь создать диаграмму с накоплением, используя количество неудачных попыток входа в систему и количество успешных входов в систему. Вот как выглядят мои таблицы:

Таблица Success_login:

User_ID  Site_Address  Login_Attempts
1        xxx.xxx.xxx   5
2        xxx.xxy.yyy   10

Таблица Fail_login:

User_ID  Site_Address  Login_Attempts
1        xxx.xxx.xxx   2
2        xxx.xxy.yyy   8

Как использовать столбцы Login_Attempts этих двух таблиц для создания диаграммы с накоплением, чтобы я мог выделить успешную и неудачную попытку? Я поискал в Интернете и нашел этот код:

# Stacked Bar Plot with Colors and Legend
 counts <- table(mtcars$vs, mtcars$gear)
 barplot(counts, main="Car Distribution by Gears and VS",
 xlab="Number of Gears", col=c("darkblue","red"),
 legend = rownames(counts))

Однако это не работает, поскольку в моих двух таблицах разное количество записей. Буду признателен, если вы поможете мне найти решение.

Спасибо


person KMC    schedule 24.03.2015    source источник
comment
Предоставьте воспроизводимый пример, который включает ваши данные в воспроизводимом формат (например, включив вывод dput в ваш вопрос).   -  person Thomas    schedule 24.03.2015


Ответы (2)


Обсуждение

Сначала вам нужно объединить ваши данные в единую таблицу. Это можно сделать с помощью внешнего соединения, если вы знакомы с SQL. См. Как объединить (объединить) фреймы данных ( внутренний, внешний, левый, правый)?. Результирующие NAs (для записей, которые не смогли присоединиться к противоположной таблице) должны быть заменены нулями, чтобы последний вызов barplot() работал.

Затем вы должны вывести матрицу в формате, требуемом barplot() для создания гистограмм с накоплением, что довольно легко сделать с помощью одного вызова matrix(). Позаботившись о том, чтобы правильно установить метки / заголовки / легенды / цвета, вы можете получить красивую гистограмму с накоплением:

Код

s <- data.frame(User_ID=c(1,2,3), Site_Address=c('xxx.xxx.xxx','xxx.xxy.yyy','xxx.yyy.zzz'), Login_Attempts=c(5,10,3) );
f <- data.frame(User_ID=c(1,2,4), Site_Address=c('xxx.xxx.xxx','xxx.xxy.yyy','xxx.yyy.zzz'), Login_Attempts=c(2,8,4) );
all <- merge(s,f,by=c('User_ID','Site_Address'),suffixes=c('.successful','.failed'),all=T);
all[is.na(all)] <- 0;
stackData <- matrix(c(all$Login_Attempts.failed, all$Login_Attempts.successful ),2,byrow=T);
colnames(stackData) <- paste0(all$User_ID, '@', all$Site_Address );
rownames(stackData) <- c('failed','successful');
barplot(stackData,main='Successful and failed login attempts',xlab='User_ID@Site_Address',ylab='Login_Attempts',col=c('red','blue'),legend=rownames(stackData));

Результирующие данные

r> s;
  User_ID Site_Address Login_Attempts
1       1  xxx.xxx.xxx              5
2       2  xxx.xxy.yyy             10
3       3  xxx.yyy.zzz              3
r> f;
  User_ID Site_Address Login_Attempts
1       1  xxx.xxx.xxx              2
2       2  xxx.xxy.yyy              8
3       4  xxx.yyy.zzz              4
r> all;
  User_ID Site_Address Login_Attempts.successful Login_Attempts.failed
1       1  xxx.xxx.xxx                         5                     2
2       2  xxx.xxy.yyy                        10                     8
3       3  xxx.yyy.zzz                         3                     0
4       4  xxx.yyy.zzz                         0                     4
r> stackData;
           [email protected] [email protected] [email protected] [email protected]
failed                 2             8             0             4
successful             5            10             3             0

Выход

гистограмма

использованная литература


Изменить: немного странно создавать линейчатую диаграмму с накоплением в один столбец, но хорошо, вот как это можно сделать, используя приведенные выше данные (all) в качестве основы:

barplot(matrix(c(sum(all$Login_Attempts.failed),sum(all$Login_Attempts.successful))),main='Successful and failed login attempts',ylab='Login_Attempts',col=c('red','blue'),legend=c('failed','successful'));

одна столбчатая диаграмма


Изменить: Да, ось Y действительно должна полностью покрывать стек по умолчанию, это слабое место в базовом графическом пакете, которого она не делает. Вы можете добавить ylim=c(0,1.2*sum(do.call(c,all[,3:4]))) в качестве аргумента к вызову barplot(), чтобы заставить ось Y выходить как минимум на 20% за верхнюю точку стека. (К сожалению, вам приходится вычислять это вручную на основе входных данных, но, как я уже сказал, это слабое место в пакете.)

Кроме того, что касается моего комментария о единстве столбца, просто для сравнения нескольких столбцов чаще используются составные столбчатые диаграммы, а не для отображения одного столбца. (Вот почему я изначально предполагал, что вам нужна отдельная полоса для каждого пользователя / сайта.) Вместо одной сложенной полоски обычно вы видите простую старую гистограмму, показывающую рядом разные точки данных. Но это действительно зависит от вашего приложения, поэтому делайте то, что лучше всего подходит для вас.

person bgoldst    schedule 24.03.2015
comment
Спасибо! Я должен был очистить, но то, что я искал, - это сравнить общую сумму успеха и неудачи всех пользователей. Не отдельные пользователи. Таким образом, будет только одна планка, которая будет накладываться одна на другую. Я использовал rowSums, чтобы суммировать вашу гистограмму данных (rowSums (stackData) ... но это приводит к двум столбцам. Есть идеи, почему? - person KMC; 24.03.2015
comment
Спасибо!! Не могли бы вы объяснить, почему вы считаете странным создавать линейку из одного бара? И есть ли способ удлинить ось Y так, чтобы она содержала полосу? - person KMC; 24.03.2015

  1. Попробуйте нарисовать вручную диаграмму с накоплением, которую вы пытаетесь создать. Это вообще имеет смысл?
  2. Убедившись, что теперь вы знаете, как должен выглядеть желаемый результат, вручную создайте единственный data.frame или матрицу, необходимую barplot для создания вашего результата. Не забудьте указать особые экземпляры, например где у пользователя есть только успешные или неудачные входы в систему.
  3. Подумайте, как объединить ваши входные data.frames в один data.frame на предыдущем шаге.

Результат шага 2 - ваш воспроизводимый пример, который вам нужен, чтобы задать здесь разумный вопрос. Шаг 3 - это то, о чем вы спрашиваете здесь, но, похоже, вы не уверены, как должен выглядеть промежуточный результат. Шаг 1 - это визуализация конечного продукта и дальнейшая работа с ним.

person MrGumble    schedule 24.03.2015