Как перебирать столбцы и создавать 2 разных графика, используя одни и те же данные

Я новичок в R и попытался создать код, который помогает мне перебирать большой набор данных и тем самым создавать 2 графика на столбец. При этом он должен учитывать некоторые указанные переменные и различать их (см. Код). На первом графике он должен создать коробчатую диаграмму / диаграмму рассеяния, где мне нужно различать контрольную и больную когорты. в дополнение к этому я хочу увидеть разницу между людьми, у которых есть событие, и людьми, у которых нет события.

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

Кроме того, я хотел бы объединить оба графика на 1 страницу и в конце цикла через весь набор переменных и сохранить его как изображение (см. Код)

пожалуйста, найдите ниже код, который у меня есть. Любые предложения очень ценятся

library(ggplot2)
library(purrr)

Создайте фрейм данных со случайными числами и 2 группами

group <- c("Control","PAD","Control","PAD","PAD", "Control","PAD","Control","PAD","PAD", "Control","PAD","Control","PAD","PAD")
b <- round(runif(15, 1, 7)) 
c <- round(runif(15, 1, 3)) 
d <- round(runif(15, 3, 8)) 
e <- round(runif(15, 1, 5))
event <- c("no event", "event" , "no event" , "no event" , "no event", "no event", "event", "no event", "no event" , "no event" , "no event" , "no event", "no event", "event", "event")

Присоединяйтесь к переменным, чтобы создать фрейм данных

df <- data.frame(group, b,c,d, e, event)
df

rm(group, b, c, d, e, event)

создать новый цвет, который дает определенный цвет меткам (используется # для цветовой маркировки групп на 1 графике)

df$color <- "color"
for (i in 1:dim(df)[1]){
  if (df$group[i]=="Control") {
    df$color[i] <- "Control" # in de column PAD, if the control is control give the color the string "control"
  }
}
for (i in 1:dim(df)[1]){
  if (df$group[i] == "PAD" && df$event[i] == "event") {
    df$color[i] <- "PAD with event" # in de column PAD, if the PAD has event give the color the string "event"
  }
}
for (i in 1:dim(df)[1]){
  if (df$group[i] == "PAD" && df$event[i] == "no event") {
    df$color[i] <- "PAD without event"
  }
}
rm(i)

вытащить имена по индексу, создать 1 пояснительную переменную, используемую в качестве пояснительного значения (столбец 1)

expl = names(df[1]) 

используется для прокрутки столбцов 2: 5

response = names(df[2:5]) 

использовать именованные векторы

response = set_names(response)
response

expl = set_names(expl)
expl

диаграмма рассеивания первая часть функции работает ЧАСТЬ 1 функции

scatter_fun = function(x, y) {
  ggplot(df, aes(x = .data[[x]], y = .data[[y]], color=color) ) + 
    geom_boxplot(fill="lightgrey", colour= "black", alpha=0.7,  
                 outlier.shape=NA) + 



geom_point(position = position_jitter(0.2)) +
    scale_color_manual(values= c("Control"="Orange", "PAD with event" = "Red", "PAD without event"="Green")) + # color the values as as you please
    labs(x = "",
         y = y,
         caption = "") +
    theme_bw() +
    theme(panel.grid.major = element_line(size = 0.1, linetype = 'solid',
                                          colour = "grey"), 
          panel.grid.minor = element_line(size = 0.05, linetype = 'solid',
                                          colour = "grey"),

          legend.title = element_blank(),
          legend.text = element_text(size=13),
          legend.key.size = unit(3,"line"))

ЧАСТЬ 2 функции (которая не работает) добавляет гистограмму к функции, это та часть, где для меня это усложняется. Я хочу получить 3 вещи из функции 1, верхняя часть, которая дает мне коробчатую диаграмму в сочетании с диаграммой рассеяния 2, часть ниже, где я хочу иметь гистограмму зацикленного столбца (в данном случае b), чтобы получить представление о распределение значения 3 С помощью функции в конце я хотел бы передать оба столбца на одной странице два файла PDF, просматривая столбцы, чтобы получить представление о том, что происходит на этом графике, можно удалить, и пример ниже может использоваться для получения примера добавления гистограммы к функции

ggplot(df, aes(x =.data[[x]])) +
    geom_histogram(fill="Orange", color="black", stat = "count")

}

пример того, как это работает, когда вы просто указываете имя столбца

loopplots = map(expl, ~scatter_fun(.x, "b") ) 
loopplots

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

весь цикл: когда я запускаю эту часть, сохраняется только последняя часть функции

event_vs_no_event = map(response,
                        ~map(expl, scatter_fun, y = .x) )

проверьте, что сохранено на б

event_vs_no_event$b

сохранить все изображения в 1 PDF -> здесь я хочу, чтобы и гистограмма, и диаграмма рассеяния соответствовали 1 столбцу, сохраненному на 1 странице.

pdf("event_vs_no_event.pdf")
event_vs_no_event
dev.off() 

введите описание изображения здесь


person Jens    schedule 11.11.2019    source источник


Ответы (1)


Рекомендую использовать sth. это как отправная точка. Гораздо удобнее использовать длинные фреймы данных с ggplot, чем широкие. Здесь я использую gather tidyr для создания длинного фрейма данных.

library(tidyverse)
p1 <- df %>% 
  gather(response , value, -group, -event) %>% 
  ggplot(aes(group, value, color = event)) + 
   geom_boxplot(show.legend = F) + 
   geom_point(position = position_dodge(width = 0.8), show.legend = F) +  
   facet_wrap(~response, scales = "free_y")

p2 <- df %>% 
  gather(response , value, -group, -event) %>% 
  ggplot(aes(value)) + 
  geom_histogram(fill="Orange", color="black", bins= 6) + 
  facet_wrap(~response, scales = "free") 

library(cowplot)

plot_grid(p1, p2, ncol = 1)

введите описание изображения здесь

ИЗМЕНИТЬ

Самый аккуратный способ без петель - s.th. нравится.

library(ggbeeswarm)
library(cowplot)
library(tidyverse)
plots <- df %>% 
  gather(response , value, -group, -event) %>% 
  nest(-response) %>% 
  mutate(box_scatter = map2(data, response, ~ggplot(.x,aes(group, value)) + 
        geom_boxplot(show.legend = F) + 
        geom_beeswarm(aes(color = event)) +
        ggtitle(.y))) %>% 
  mutate(hist = map(data, ~ ggplot(.,aes(value)) + 
                      geom_histogram(fill="Orange", color="black", bins= 6)+
                      ggtitle("")))

pdf("all_plots.pdf", width = 15)
map2(plots$box_scatter, plots$hist, 
    ~plot_grid(.x, .y, ncol = 2, labels ="auto"))
dev.off()

Но, конечно, вы также можете использовать цикл for

pdf("all_plots.pdf", width = 15)
for (i in names(df)[2:5]){
  p1 <- ggplot(df, aes_string("group",i)) + 
    geom_boxplot(show.legend = F) + 
    geom_beeswarm(aes(color = event))

  p2 <- ggplot(df,aes_string(i)) + 
    geom_histogram(fill="Orange", color="black", bins= 6)

  p_all <- plot_grid(p1, p2)
  print(p_all)
} 
dev.off()
person Roman    schedule 11.11.2019
comment
Однако есть одна проблема, но, возможно, это мой недостаток опыта в кодировании с R. У меня есть 290 переменных, которые я хочу визуализировать, как в приложении: 1 диаграмма разброса / прямоугольная диаграмма и соответствующая гистограмма на 1 странице. затем перейдите к следующему столбцу и воспроизведите то же самое, но со следующей переменной. В конце концов, я хочу напечатать это: 1 переменная (два графика) на страницу. Я добавил вложение, чтобы вы могли увидеть, как это должно выглядеть. - person Jens; 12.11.2019