Как создавать график (водопада “waterfall диаграмма”) с ggplot2?

Система поколения графиков R ggplot2 он удивительно переменчивый, но я не нашел способ производить график водопада (waterfall диаграмма) сходная с этим:

Waterfall chart

Как я могу, используя ggplot2, производить этот тип графика?


Данные о примере (сходные с данными показанного графика:

df <- data.frame(
  montos = c(420, 210, -170, -140),
  row.names = c('Ingresos', 'Otros ingresos', 'Costos fijos', 'Costos variables')
)
df
##                  montos
## Ingresos            420
## Otros ingresos      210
## Costos fijos       -170
## Costos variables   -140

13
задан 15.12.2015, 00:20
2 ответа

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

1. Инициализировать данные

Как ты это поместил в вопрос, инициализация была бы нечто похожим (только я изменился row.names из-за nombres чтобы помещать оба на испанском языке) и я добавил начальный окончательный расчет и конец:

df <- data.frame(
  montos = c(100, 320, 210, -170, -140, 320),
  nombres = c('Saldo Inicial', 'Ingresos', 'Otros ingresos', 'Costos fijos', 'Costos variables', 'Saldo Final')
)

Мы подтверждаем, что все, как мы желаем:

df

## nombres           montos
## Saldo Inicial       100
## Ingresos            320
## Otros ingresos      210
## Costos fijos       -170
## Costos variables   -140
## Saldo Final         320

2. Предохранять порядок

Чтобы предохранять порядок данных мы должны конвертировать nombres в тип информации factor.

df$desc <- factor(df$nombres, levels = df$nombres)

3. Добавлять колонны

Мы добавляем колонну id и одна tipo

df$id <- seq_along(df$montos)
df$tipo <- ifelse(df$montos > 0, "in", "out") # Si es positivo será un ingreso y en caso contrario será un egreso
df[df$nombres %in% c("Saldo Inicial", "Saldo Final"), "tipo"] <- "net" # Esto es para el balance inicial y final

Потом мы добавляем две колонны, start и end, это, чтобы помещать начальную и конечную стоимость общей суммы в каждый шаг:

df$end <- cumsum(df$montos)
df$end <- c(head(df$end, -1), 0)
df$start <- c(0, head(df$end, -1))

Если я не ошибся, ты df это быть должный выглядеть так:

## id  tipo  nombres           start end  montos
## 1   net   Saldo Inicial     0     100  100
## 2   in    Ingresos          100   420  320
## 3   in    Otros ingresos    420   630  210
## 4   out   Costos fijos      630   460 -170
## 5   out   Costos variables  460   320 -140
## 6   net   Saldo Final       320   0    320

4. Производить график

Сейчас да, чтобы производить график, мы делаем следующее:

library(ggplot2)
ggplot(df, aes(nombres, fill = tipo)) + geom_rect(aes(x = nombres,
       xmin = id - 0.45, xmax = id + 0.45, ymin = end,
       ymax = start))

5. Результат

Resultado Главным образом это было бы совсем. Ему может делаться какой-то прогресс, в зависимости от которого я заинтересовал тебя в графике, оказанный.

Ты можешь видеть полный код в этом demo.

6. Дополнительные

Это заменяет место разрывами линии для того, чтобы были читабельнее ценные бумаги.

strwr <- function(str) gsub(" ", "\n", str)
(p1 <- ggplot(df, aes(fill = tipo)) + geom_rect(aes(x = nombres,
    xmin = id - 0.45, xmax = id + 0.45, ymin = end,
    ymax = start)) + 
    scale_x_discrete("", breaks = levels(df$nombres),
    labels = strwr(levels(df$nombres))) +
    theme(legend.position = "none")
)

introducir la descripción de la imagen aquí

11
ответ дан 24.11.2019, 15:06

Как альтернатива ты можешь использовать пакет waterfall , осуществленные с lattice ( я осаждаю автора ).

Пример:

library(latticeExtra)
library(waterfall)

df <- data.frame(
  montos = c(420, 210, -170, -140),
  names = c('Ingresos', 'Otros ingresos', 'Costos fijos', 'Costos variables')
)
df$names <- factor(df$names, levels=unique(df$names))
df

##                  montos
## Ingresos            420
## Otros ingresos      210
## Costos fijos       -170
## Costos variables   -140

waterfallchart(montos ~ names, data=df, main="Waterfall graph")

, Оказанные в: R-Fiddle

6
ответ дан 24.11.2019, 15:06