Ben bir boşluk düzeni (kullanılabilir değil ) ile bir faset düzeni sağlar - ancak birden çok sütun üzerinde işlevine facet_multi_col()
benzer bir işlev oluşturmaya çalışıyorum . Aşağıdaki son çizimde olduğu gibi (ile oluşturulmuştur ) her modeldeki yüksekliklerin kullanmak istediğim kategorik bir değişkene bağlı olarak değişeceğinden, fasetlerin mutlaka sıralar arasında hizalanmasını istemiyorum.facet_col()
ggforce
facet_wrap()
grid.arrange()
y
ggproto
Uzatma kılavuzunu okuduğumda kendimi derinliğimden iyi buluyorum . En iyi yaklaşım verinin karşılık gelen alt kümeleri için sütun kırmak için bir düzen matris geçmek ve bir boşluk parametresi eklemek için facet_col
ggforce içinde inşa etmek olduğunu düşünüyorum - sorunun sonuna bakın.
Tatmin edici seçeneklerimin kısa bir açıklaması
Faset yok
library(tidyverse)
library(gapminder)
global_tile <- ggplot(data = gapminder, mapping = aes(x = year, y = fct_rev(country), fill = lifeExp)) +
geom_tile()
global_tile
Arsaları kıtalar tarafından yıkmak istiyorum. Böyle uzun bir figür istemiyorum.
facet_wrap ()
global_tile +
facet_wrap(facets = "continent", scales = "free")
facet_wrap()
kullanılarak, fayans, her kıtada farklı boyutlarda olduğu anlamına gelir bir boşluk bağımsız değişken olmayan coord_equal()
bir hata verir
ggforce içinde facet_col ()
library(ggforce)
global_tile +
facet_col(facets = "continent", scales = "free", space = "free", strip.position = "right") +
theme(strip.text.y = element_text(angle = 0))
Yandaki şeritler gibi. space
argümanı tüm döşemeleri aynı boyuta ayarlar. Bir sayfaya sığmayacak kadar uzun.
gridExtra içinde grid.arrange ()
Her kıtanın nereye yerleştirileceğine ilişkin verilere sütun sütunu ekleyin
d <- gapminder %>%
as_tibble() %>%
mutate(col = as.numeric(continent),
col = ifelse(test = continent == "Europe", yes = 2, no = col),
col = ifelse(test = continent == "Oceania", yes = 3, no = col))
head(d)
# # A tibble: 6 x 7
# country continent year lifeExp pop gdpPercap col
# <fct> <fct> <int> <dbl> <int> <dbl> <dbl>
# 1 Afghanistan Asia 1952 28.8 8425333 779. 3
# 2 Afghanistan Asia 1957 30.3 9240934 821. 3
# 3 Afghanistan Asia 1962 32.0 10267083 853. 3
# 4 Afghanistan Asia 1967 34.0 11537966 836. 3
# 5 Afghanistan Asia 1972 36.1 13079460 740. 3
# 6 Afghanistan Asia 1977 38.4 14880372 786. 3
tail(d)
# # A tibble: 6 x 7
# country continent year lifeExp pop gdpPercap col
# <fct> <fct> <int> <dbl> <int> <dbl> <dbl>
# 1 Zimbabwe Africa 1982 60.4 7636524 789. 1
# 2 Zimbabwe Africa 1987 62.4 9216418 706. 1
# 3 Zimbabwe Africa 1992 60.4 10704340 693. 1
# 4 Zimbabwe Africa 1997 46.8 11404948 792. 1
# 5 Zimbabwe Africa 2002 40.0 11926563 672. 1
# 6 Zimbabwe Africa 2007 43.5 12311143 470. 1
facet_col()
Her sütun için çizim için kullanın
g <- list()
for(i in unique(d$col)){
g[[i]] <- d %>%
filter(col == i) %>%
ggplot(mapping = aes(x = year, y = fct_rev(country), fill = lifeExp)) +
geom_tile() +
facet_col(facets = "continent", scales = "free_y", space = "free", strip.position = "right") +
theme(strip.text.y = element_text(angle = 0)) +
# aviod legends in every column
guides(fill = FALSE) +
labs(x = "", y = "")
}
Kullanarak bir açıklama oluşturmak get_legend()
içindecowplot
library(cowplot)
gg <- ggplot(data = d, mapping = aes(x = year, y = country, fill = lifeExp)) +
geom_tile()
leg <- get_legend(gg)
Her sütundaki ülke sayısına göre yüksekliklerle bir düzen matrisi oluşturun.
m <-
d %>%
group_by(col) %>%
summarise(row = n_distinct(country)) %>%
rowwise() %>%
mutate(row = paste(1:row, collapse = ",")) %>%
separate_rows(row) %>%
mutate(row = as.numeric(row),
col = col,
p = col) %>%
xtabs(formula = p ~ row + col) %>%
cbind(max(d$col) + 1) %>%
ifelse(. == 0, NA, .)
head(m)
# 1 2 3
# 1 1 2 3 4
# 2 1 2 3 4
# 3 1 2 3 4
# 4 1 2 3 4
# 5 1 2 3 4
# 6 1 2 3 4
tail(m)
# 1 2 3
# 50 1 2 NA 4
# 51 1 2 NA 4
# 52 1 2 NA 4
# 53 NA 2 NA 4
# 54 NA 2 NA 4
# 55 NA 2 NA 4
Getir g
ve leg
birlikte kullanılarak grid.arrange()
içindegridExtra
library(gridExtra)
grid.arrange(g[[1]], g[[2]], g[[3]], leg, layout_matrix = m, widths=c(0.32, 0.32, 0.32, 0.06))
Neredeyse peşinde olduğum şey bu, ama memnun değilim a) farklı sütunlardaki fayanslar en uzun ülke uzunluğu ve kıta isimleri eşit olmadığı için farklı genişliklere sahip ve b) her birinin değiştirilmesi gereken çok fazla kod var zaman böyle bir komplo yapmak istiyorum - diğer verilerle fasetleri kıtalardan ziyade bölgelere göre düzenlemek istiyorum, örneğin "Batı Avrupa" ya da ülke sayısı değişiyor - gapminder
verilerde Orta Asya ülkeleri yok .
Bir facet_multi_cols () işlevi oluşturma işleminde ilerleme
Bir düzen matrisini, matrisin her bir yüze atıfta bulunduğu bir faset fonksiyonuna geçirmek istiyorum ve fonksiyon daha sonra her paneldeki boşluk sayısına göre yükseklikleri anlayabilir. Yukarıdaki örnek için matris şöyle olacaktır:
my_layout <- matrix(c(1, NA, 2, 3, 4, 5), nrow = 2)
my_layout
# [,1] [,2] [,3]
# [1,] 1 2 4
# [2,] NA 3 5
Yukarıda belirtildiği gibi, ben facet_col()
bir facet_multi_col()
işlev denemek ve oluşturmak için kod adapte edilmiştir . Yukarıdaki layout
gibi matris sağlamak my_layout
için facets
argümana verilen değişkenin dördüncü ve beşinci seviyesinin üçüncü sütunda çizildiği fikrini ekledim .
facet_multi_col <- function(facets, layout, scales = "fixed", space = "fixed",
shrink = TRUE, labeller = "label_value",
drop = TRUE, strip.position = 'top') {
# add space argument as in facet_col
space <- match.arg(space, c('free', 'fixed'))
facet <- facet_wrap(facets, col = col, dir = dir, scales = scales, shrink = shrink, labeller = labeller, drop = drop, strip.position = strip.position)
params <- facet$params
params <- facet$layout
params$space_free <- space == 'free'
ggproto(NULL, FacetMultiCols, shrink = shrink, params = params)
}
FacetMultiCols <- ggproto('FacetMultiCols', FacetWrap,
# from FacetCols to allow for space argument to work
draw_panels = function(self, panels, layout, x_scales, y_scales, ranges, coord, data, theme, params) {
combined <- ggproto_parent(FacetWrap, self)$draw_panels(panels, layout, x_scales, y_scales, ranges, coord, data, theme, params)
if (params$space_free) {
widths <- vapply(layout$PANEL, function(i) diff(ranges[[i]]$x.range), numeric(1))
panel_widths <- unit(widths, "null")
combined$widths[panel_cols(combined)$l] <- panel_widths
}
combined
}
# adapt FacetWrap layout to set position on panels following the matrix given to layout in facet_multi_col().
compute_layout = function(self, panels, layout, x_scales, y_scales, ranges, coord, data, theme, params) {
layout <- ggproto_parent(FacetWrap, self)$compute_layout(panels, layout, x_scales, y_scales, ranges, coord, data, theme, params)
# ???
)
Sanırım compute_layout
rol için bir şeyler yazmam gerekiyor, ama bunun nasıl yapılacağını anlamaya çalışıyorum.
grid.arrange
Yukarıdaki örnekte ... farklı bir şey ifade etmedikçe yaptım ? Her sütunda farklı etiket uzunlukları ile aynı sorunları olacağını düşünüyorum?
grid.arrange
. Bu gerçekten uzun bir gönderi, bu yüzden denediğiniz her şeyi takip etmek zor. Biraz hacky, ama etiketler için tek aralıklı bir yazı tipine daha yakın bir tek boşluk / yakın deneyebilirsiniz, böylece uzunlukları daha tahmin edilebilir. Daha sonra, metnin aynı uzunluğa daha yakın olduğundan emin olmak için etiketleri boş boşluklarla doldurabilirsiniz.