"Ошибка: эстетика должна быть либо длины 1, либо такой же, как данные (1148)…". Почему?
Уикхем (2009: 164-6) приводит пример построения нескольких временных рядов одновременно. Следующий код повторяет его пример:
range01 <- function(x) {
rng <- range(x, na.rm = TRUE)
(x - rng[1])/diff(rng)
}
emp <- subset(economics_long, variable %in% c("uempmed", "unemploy"))
emp2 <- ddply(emp, .(variable), transform, value = range01(value))
qplot(date, value, data = emp2, geom = "line", color = variable, linetype = variable)
# Produces a plot that looks like the one on p. 166 of the ggplot2 book.
Здесь range01 используется для перекодирования переменных в значения в пределах [0,1], поэтому ряды с различными порядками величины могут быть нанесены на одинаковые шкалы. Оригинал Уикхема также начинается с employment
данные, предоставляемые ggplot2 и расплавляют его в длинную форму, но здесь я взял ярлык, начиная с employment_long
версия.
Но Уикхем (стр. 27) также указывает, что использование "полной мощности" ggplot2 требует ручного построения графиков по слоям с использованием функции ggplot(). Вот снова его пример, но с использованием ggplot() вместо qplot ():
# Now do the same thing using ggplot commands only
ggplot(data = emp2, aes(x = date)) +
geom_line(aes(y = value, group = variable, color = variable, linetype = variable))
# Get the same results
В обоих примерах используются стандартные настройки ggplot2. Но предположим, что мы хотим большего контроля над эстетикой. Возможно, некоторые переменные поддаются определенным цветовым схемам (например, зеленый может использоваться для экологически чистых переменных, а черный - для вредных); или, возможно, в длинной монографии со множеством сюжетов мы просто хотим обеспечить последовательность. Кроме того, если графики будут использоваться как в презентациях, так и в печатном черно-белом тексте, мы также можем захотеть связать определенные типы линий с конкретными сериями; это также может иметь место, если мы обеспокоены зрителями с дальтонизмом. Наконец, имена переменных обычно являются плохими дескрипторами того, что на самом деле являются переменными, поэтому мы хотим связать метки переменных с отдельными временными рядами.
Таким образом, мы определяем следующее для набора данных экономики:
# Try to control the look a bit more
economics_colors = c("pce" = "red", "pop" = "orange", "psavert" = "yellow",
"uempmed" = "green", "unemploy" = "blue")
economics_linetypes = c("pce" = "solid", "pop" = "dashed", "psavert" = "dotted",
"uempmed" = "dotdash", "unemploy" = "longdash")
economics_labels = c(
"pce" = "Personal consumption expenditures",
"pop" = "Total population",
"psavert" = "Personal savings rate",
"uempmed" = "Median duration of unemployment",
"unemploy" = "Number of unemployed"
)
Теперь построим график, добавив отдельные слои (Wickham 2009: 164-5) для каждой переменной:
# First do it line-by-line
employment.plot <- ggplot(emp2) + aes(x = date) +
scale_linetype_manual(values = economics_linetypes, labels = economics_labels)
employment.plot <- employment.plot +
geom_line(data = subset(emp2, variable == "uempmed"),
aes(y = value, linetype = "uempmed"), color = economics_colors["uempmed"])
employment.plot <- employment.plot +
geom_line(data = subset(emp2, variable == "unemploy"),
aes(x = date, y = value, linetype = "unemploy"), color = economics_colors["unemploy"])
employment.plot
# Except for the specific line colors, produces the same plot as before.
Обратите внимание на две вещи здесь. Во-первых, типы линий отображаются, но цвета устанавливаются (см. Wickham 2009: 47-49). Это приводит к желаемому результату одной легенды с различными комбинациями цветов и типов линий для каждой серии.
Во-вторых, хотя данные организованы в "длинном" формате, мы использовали подмножество для выбора отдельных серий. Это не лучшее решение. Как говорит Уикхем (164-5):
... лучшая альтернатива состоит в том, чтобы преобразовать данные в длинный формат и затем визуализировать это. В расплавленных данных временные ряды хранят свои значения в переменной value, и мы можем различать их с помощью переменной variable.
Итак, давайте попробуем этот подход:
# Now try it the automatic way
employment.plot <- ggplot(data = emp2, aes(x = date)) +
scale_linetype_manual(values = economics_linetypes, labels = economics_labels)
employment.plot <- employment.plot +
geom_line(aes(y = value, group = variable, linetype = economics_linetypes), color = economics_colors)
employment.plot
# Throws "Error: Aesthetics must be either length 1 or the same as the data (1148) ..."
Как указано в комментарии, этот код выдает ошибку, касающуюся эстетики. Зачем?
Кроме того, существует ли другой способ достижения нескольких целей использования расплавленных данных с одной переменной переменной, запускающей отдельные строки, контролирующей, какие цвета и типы линий связаны с каждой серией, и использования кода для стандартизации таких соглашений на нескольких графиках?
Рекомендации
Уикхем, Хэдли. 2009. ggplot2: Элегантная графика для анализа данных. Springer.
1 ответ
Эстетика всегда должна быть сопоставлена с размером набора данных.
Что вы говорите с последней командой: "Для каждой" точки данных "(или группы в данном случае) назначьте тип линии, равный ее economics_linetypes
".
Но пока нет информации о том, как сопоставить каждую запись (группу) с каким-либо значением в economics_linetypes
, Так что это справедливо вернет ошибку.
Что вы должны сделать, это сопоставить linetype
в измерение, которое управляет им. То есть: "для каждого значения в этом измерении используйте другое значение linetype
то есть
geom_line(aes(y = value, group = variable, linetype = variable)
Как только мы определим это, мы можем отобразить значение переменной на конкретный linetype
с определением шкалы:
scale_linetype_manual(values = economics_linetypes, labels = economics_labels)
Разумеется, все это относится и к цвету, поэтому в итоге мы имеем:
employment.plot <- ggplot(data = emp2, aes(x = date)) +
geom_line(aes(y = value, group = variable, linetype = variable, color = variable)) +
scale_linetype_manual(values = economics_linetypes, labels = economics_labels) +
scale_color_manual(values = economics_colors, labels = economics_labels)
Надеюсь, это достаточно ясно.