Я пытаюсь составить график, показывающий количество калорий для разных видов сэндвичей в магазине сэндвичей. То есть сколько калорий имеет вегетарианский бутерброд в метро против Джимми Джона и т. д.

Я хотел бы представить это как барплот, что

  • есть бар для калорийности каждого сэндвича

  • заметно группирует бутерброды по типу : вегетарианец , ростбиф и т. д., где каждая группа разделена в соответствии с различными поставщиками.

Мои данные выглядят так (РЕДАКТИРОВАНИЕ для воспроизводимости):

cleaninput <- data.frame ("type" = c("italian", "turkey", "roastbeef", "club", "veggie", "italian", "turkey", "roastbeef", "veggie"), 
"vendor" = c( "subway",  "subway",  "subway",  "subway",  "subway",  "jimmyjohns", "jimmyjohns", "jimmyjohns", "jimmyjohns"),
"calories" = c(410,280,320,310,230,640,510,540,690))

Я пытаюсь перебрать данные так, где cleaninput - это мой data.frame:

#set up barplot
barplot(height = mean(cleaninput[['calories']]))
#iterate over sandwich types
for (t in levels(cleaninput[['type']]))
{
  cat(t,"\n")

  barplot(cleaninput[cleaninput[['type']]==t,][['calories']], add = TRUE)
}

Идея заключается в том, чтобы сначала настроить барплот, а затем итеративно добавить бары для каждого типа сэндвича. Я понял { {X0}} настройки для этого. Я делал подобные вещи с обычными графиками, используя команды lines и points и воспроизводя приведенный ниже пример - это то, что я хочу перенести в график.

enter image description here

Тем не менее, это не работает, так как кажется, что все столбцы расположены друг над другом (см. Ниже).

Мои вопросы

  • (Как я могу это исправить? Предпочтительно я хотел бы использовать базу R, а не ggplot, чтобы сделать это более переносимым.

  • Есть ли лучший подход, чем for - цикл?

Я просмотрел учебники для сгруппированных барплотов, но не увидел, как они перешли на мою проблему.

Токовый выход:

ugly R plot

0
patrick 29 Май 2017 в 00:12

2 ответа

Лучший ответ

Вот решение в базовом графике в соответствии с запросом, так как это ваше предпочтение над ggpltot2.

Первый шаг - получить ваши данные в широкоформатном формате, используемом на базовом графике для барплотов, например. используя reshape2::dcast или tidyr::spread

library(tidyr)
library(tidyverse)
cleaninput_spread <- cleaninput %>% spread(type, calories) %>% remove_rownames %>% column_to_rownames(var="vendor")
cleaninput_spread

>            club italian roastbeef turkey veggie
> jimmyjohns   NA     640       540    510    690
> subway      310     410       320    280    230

Заменить значения NA на 0:

cleaninput_spread[is.na(cleaninput_spread)] <- 0

Сложенный барплот в базе:

barplot(as.matrix(cleaninput_spread), main="Calories per Sandwich, by shop",
        xlab="Sandwich", ylab="Calories",
        col=c("darkblue","red"),
        legend = rownames(cleaninput_spread))

enter image description here

1
Djork 10 Июн 2017 в 21:06

Это то, что вы ищите?

type<-c("italian","turkey","roastbeef","club","veggie","italian","turkey","roastbeef","veggie")
vendor<-c(rep("subway",5),rep("jimmyjohns",4))
calories<-c(410,280,320,310,230,640,510,540,690)
size<-c(rep(6,5),rep(8,4))

cleaninput<-data.frame(type,vendor,calories,size)

#first you calculate the mean by type using by function (base package)  

calor.by.type<-by(cleaninput$calories,INDICES = list(cleaninput$type),FUN = mean)

#then you plot the result from by function

barplot(calor.by.type,main="by function")

enter image description here

1
storm surge 29 Май 2017 в 16:02