Создание многоуровневой диаграммы
У меня есть две таблицы, в которых хранятся попытки входа пользователей. Одна таблица содержит все успешные логины, а другая-неудачные попытки. Я пытаюсь создать диаграмму с накоплением, используя количество неудачных входов и количество успешных входов. Вот как выглядят мои таблицы:
Таблица 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))
Однако это не работает, так как мои две таблицы имеют разное количество записей. Я был бы признателен, если бы вы помогли мне найти решение.
Спасибо
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Вывод
Ссылки
- Как соединить (объединить) фреймы данных (внутренний, внешний, левый, правый)?
- R: объединить неравные фреймы данных и заменить недостающие строки на 0
- https://stat.ethz.ch/R-manual/R-devel/library/base/html/merge.html
- http://www.statmethods.net/graphs/bar.html
- https://stat.ethz.ch/R-manual/R-devel/library/graphics/html/barplot.html
- https://stat.ethz.ch/R-manual/R-devel/library/base/html/matrix.html
Edit: немного странно создавать столбчатую диаграмму с одним столбиком, но хорошо, вот как вы можете это сделать, используя вышеприведенные данные (
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'));
Edit: да, ось y действительно должна полностью покрывать стек по умолчанию, это слабое место в базовом графическом пакете, которого нет. вы можете добавить
ylim=c(0,1.2*sum(do.call(c,all[,3:4])))в качестве аргумента к вызовуbarplot(), чтобы заставить ось y расшириться по крайней мере на 20% за верхнюю точку стека. (Жаль, что вам приходится вычислять это вручную из входных данных, но, как я уже сказал, это слабое место в пакет.)Кроме того, что касается моего комментария о единстве бара, просто чаще всего для сравнения нескольких баров используются Столбчатые диаграммы, а не один бар. (Вот почему мое первоначальное предположение состояло в том, что вам нужен отдельный бар для каждого пользователя/сайта.) Вместо одного сложенного бара, обычно вы видите простую старую гистограмму, показывающую различные точки данных бок о бок. Но это действительно зависит от вашего приложения, поэтому делайте то, что лучше всего подходит для вас.
Результат шага 2-это ваш воспроизводимый пример, который вам нужен, чтобы задать здесь разумный вопрос. Шаг 3 - это то, о чем вы спрашиваете здесь, но, похоже, вы не уверены, как должен выглядеть промежуточный результат. Шаг 1 заключается в визуализации конечного продукта и последующей работе с ним.
- попробуйте нарисовать вручную сложенную диаграмму, которую вы пытаетесь создать. Есть ли в этом хоть какой-то смысл?
Убедившись, что теперь вы знаете, как должен выглядеть желаемый результат, вручную создайтеединичные данные.фрейм или матрица, необходимые дляbarplot, чтобы создать свой результат. Не забудьте включить специальные экземпляры, например, когда пользователь имеет только успешные или неудачные логины.- Определите, как поместить ваши входные данные.кадры вместе в единые данные.кадр в предыдущем шаг.


Comments