Как напечатать сгруппированные коробчатые участки на документе PDF и обозначить выбросы - PullRequest
1 голос
/ 21 января 2020

У меня есть фрейм данных, аналогичный тому, который был создан с помощью этого кода:

Location <- rep(c("FL", "GA", "SC", "NC"), each = 5)
ID <- data.frame(ID=(c(12,122,242,329,595,130,145,245,654,878,863,425,24,92,75,3,200,300,40,500)))
set.seed(1)
Copper <- sample(1:100,20,replace=T)
Iron <- sample(1:100,20,replace=T)
Carbon <- sample(1:100,20,replace=T)
Lead <- sample(1:100,20,replace=T)
Mg <- sample(1:100,20,replace=T)
CaCO <- sample(1:100,20,replace=T)
Zinc <- sample(1:100,20,replace=T)
data <- cbind(Location,State,ID,Copper,Iron,Carbon,Lead,Mg,CaCO,Zinc)

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

Я могу создать блокпосты для каждой переменной (Copper: Zinc), сгруппированные по Location следующим образом:

#example shown for Copper
library(tidyverse)
ggplot(data, aes(x=Location, y=Copper, color = Location))+
  geom_boxplot() +
  theme(axis.text.x = element_text(angle = 90, vjust = 0.3, hjust = 1)) +
  theme(legend.position = "none",
        axis.title.y = element_blank()) +
  ggtitle("Copper") + theme(plot.title = element_text(hjust = 0.5))

Я выполняю этот же процесс для каждой переменной ( Copper Zinc). Я хотел бы знать более быстрый способ выполнения sh этого - без необходимости копировать и вставлять столько - и печатать графики в PDF-документе. Должен ли я сначала использовать pivot_longer ()? Я также хотел бы знать, как маркировать только выбросы на каждом графике, используя ggplot2?

1 Ответ

1 голос
/ 21 января 2020

Использование facet_wrap для получения нескольких панелей на одном графике

Без дублирования кода для каждого элемента вы можете использовать функцию facet_wrap в ggplot2 чтобы все боксы на одной странице (которые вы можете сохранить после того, как вам нравится). (https://ggplot2.tidyverse.org/reference/facet_wrap.html)

Чтобы сделать это, вам нужно сначала изменить свою форму данных, чтобы поместить все элементы в один столбец и все значения во второй столбец, вы можете добиться этого с помощью функции pivot_longer из tidyr:

library(tidyr)
data %>% pivot_longer(.,-c(State,ID), names_to = "Element", values_to = "Value") 

# A tibble: 140 x 4
   State    ID Element Value
   <fct> <dbl> <chr>   <int>
 1 FL       12 Copper     68
 2 FL       12 Iron       89
 3 FL       12 Carbon     44
 4 FL       12 Lead       81
 5 FL       12 Mg         73
 6 FL       12 CaCO       24
 7 FL       12 Zinc       28
 8 FL      122 Copper     39
 9 FL      122 Iron       37
10 FL      122 Carbon     25
# … with 130 more rows

Теперь вы можете получить свой график, как и раньше, за исключением того, что вы указываете ggplot2 для создания отдельной панели для каждого элемента с помощью facet_wrap(~Element):

data %>% pivot_longer(.,-c(State,ID), names_to = "Element", values_to = "Value") %>%
  ggplot(aes(x = State, y = Value, color = State))+
  geom_boxplot() +
  theme(axis.text.x = element_text(angle = 90, vjust = 0.3, hjust = 1)) +
  theme(legend.position = "none",
        axis.title.y = element_blank(),
        axis.title.x = element_blank()) +
  facet_wrap(.~Element)

enter image description here

Маркировка выбросов с помощью их идентификатора

Для маркировки выбросов с помощью их ID, вы можете сначала создать новый столбец, чтобы идентифицировать их. здесь я использую dplyr для создания нового столбца (после поворота кадра данных), чтобы определить, является ли каждая точка выбросом:

DATA <- data %>% pivot_longer(.,-c(State,ID), names_to = "Element", values_to = "Value") %>%
  group_by(State, Element) %>%
  mutate(Outlier = ifelse(Value > quantile(Value,0.75)+1.5*IQR(Value) | Value < quantile(Value,0.25)-1.5*IQR(Value), "Out","in"))

# A tibble: 140 x 5
# Groups:   State, Element [28]
   State    ID Element Value Outlier
   <fct> <dbl> <chr>   <dbl> <chr>  
 1 FL       12 Copper     68 in     
 2 FL       12 Iron       37 in     
 3 FL       12 Carbon     70 in     
 4 FL       12 Lead       87 in     
 5 FL       12 Mg         45 in     
 6 FL       12 CaCO       59 in     
 7 FL       12 Zinc       43 in     
 8 FL      122 Copper     39 in     
 9 FL      122 Iron       89 in     
10 FL      122 Carbon     40 in     
# … with 130 more rows

Теперь мы можем использовать geom_text (или geom_text_repel из ggrepel пакета) для обозначения этого выброса путем поднабора кадра данных, чтобы оставить только точки, помеченные как выбросы, и использовать label = ID в качестве аргумента в aes для отображения идентификатора каждого из этих выбросов:

library(ggplot2)
library(ggrepel)
ggplot(DATA, aes(x = State, y = Value, color = State))+
  geom_boxplot() +
  geom_text_repel(data = subset(DATA, Outlier == "Out"), aes(label = ID))+
  theme(axis.text.x = element_text(angle = 90, vjust = 0.3, hjust = 1)) +
  theme(legend.position = "none",
        axis.title.y = element_blank(),
        axis.title.x = element_blank()) +
  facet_wrap(.~Element, scales = "free")

enter image description here

К l oop за сюжет, чтобы получить только один одиночный сюжет на страницу

Если вы глядя на график только одного элемента на странице и l oop по всем элементам, начиная с DATA (с выявленными выбросами), вы можете l oop по каждому значению "Element", создав for l oop:

element <- unique(DATA$Element) 
for(i in 1:length(element))
{
  g <- ggplot(subset(DATA, Element == element[i]), aes(x = State, y = Value, color = State))+
    geom_boxplot() +
    geom_text_repel(data = subset(DATA, Element == element[i] & Outlier == "Out"), aes(label = ID))+
    theme(axis.text.x = element_text(angle = 90, vjust = 0.3, hjust = 1)) +
    theme(legend.position = "none",
          axis.title.y = element_blank(),
          axis.title.x = element_blank())  +
    ggtitle(element[i]) + theme(plot.title = element_text(hjust = 0.5))
  ggsave(g,filename = paste("test",element[i],".png"), width = 5, height =5, units = "in" )
}

здесь, я сохранил его как png, но вы можете сделать то же самое для PDF или любого другого формата.

...